# HG changeset patch # User Christian Humer # Date 1449065787 -3600 # Node ID fec62e2982457cf486b450189103f77cc09a9707 # Parent 70a10a9f28ad0d9082761904cde9c65e5e30463d Rename package truffle.api.test to truffle.api to enable package-protected API access for testing. diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ArgumentsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ArgumentsTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +/** + *

Passing Arguments

+ * + *

+ * When invoking a call target with {@link CallTarget#call(Object[])}, arguments can be passed. A + * Truffle node can access the arguments passed into the Truffle method by using + * {@link VirtualFrame#getArguments}. + *

+ * + *

+ * The arguments class should only contain fields that are declared as final. This allows the + * Truffle runtime to improve optimizations around guest language method calls. Also, the arguments + * object array must never be stored into a field. It should be created immediately before invoking + * {@link CallTarget#call(Object[])} and no longer be accessed afterwards. + *

+ * + *

+ * The next part of the Truffle API introduction is at {@link com.oracle.truffle.api.FrameTest} + * . + *

+ */ +public class ArgumentsTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestRootNode rootNode = new TestRootNode(new TestArgumentNode[]{new TestArgumentNode(0), new TestArgumentNode(1)}); + CallTarget target = runtime.createCallTarget(rootNode); + Object result = target.call(new Object[]{20, 22}); + Assert.assertEquals(42, result); + } + + private static class TestRootNode extends RootNode { + + @Children private final TestArgumentNode[] children; + + TestRootNode(TestArgumentNode[] children) { + super(TestingLanguage.class, null, null); + this.children = children; + } + + @Override + public Object execute(VirtualFrame frame) { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].execute(frame); + } + return sum; + } + } + + private static class TestArgumentNode extends Node { + + private final int index; + + TestArgumentNode(int index) { + super(null); + this.index = index; + } + + int execute(VirtualFrame frame) { + return (Integer) frame.getArguments()[index]; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/CallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/CallTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +/** + *

Calling Another Tree

+ * + *

+ * A guest language implementation can create multiple call targets using the + * {@link TruffleRuntime#createCallTarget(RootNode)} method. Those call targets can be passed around + * as normal Java objects and used for calling guest language methods. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.ArgumentsTest}. + *

+ */ +public class CallTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + CallTarget foo = runtime.createCallTarget(new ConstantRootNode(20)); + CallTarget bar = runtime.createCallTarget(new ConstantRootNode(22)); + CallTarget main = runtime.createCallTarget(new DualCallNode(foo, bar)); + Object result = main.call(); + Assert.assertEquals(42, result); + } + + class DualCallNode extends RootNode { + + private final CallTarget firstTarget; + private final CallTarget secondTarget; + + DualCallNode(CallTarget firstTarget, CallTarget secondTarget) { + super(TestingLanguage.class, null, null); + this.firstTarget = firstTarget; + this.secondTarget = secondTarget; + } + + @Override + public Object execute(VirtualFrame frame) { + return ((Integer) firstTarget.call()) + ((Integer) secondTarget.call()); + } + } + + class ConstantRootNode extends RootNode { + + private final int value; + + public ConstantRootNode(int value) { + super(TestingLanguage.class, null, null); + this.value = value; + } + + @Override + public Object execute(VirtualFrame frame) { + return value; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ChildNodeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ChildNodeTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.Node.Child; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Creating a Child Node

+ * + *

+ * Child nodes are stored in the class of the parent node in fields that are marked with the + * {@link Child} annotation. The {@link Node#getParent()} method allows access to this field. Every + * node also provides the ability to iterate over its children using {@link Node#getChildren()}. + *

+ * + *

+ * A child node field must be declared private and non-final. It may only be assigned in the + * constructor of the parent node. For changing the structure of the tree at run time, the method + * {@link Node#replace(Node)} must be used (see {@link ReplaceTest}). + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.ChildrenNodesTest}. + *

+ */ +public class ChildNodeTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildNode leftChild = new TestChildNode(); + TestChildNode rightChild = new TestChildNode(); + TestRootNode rootNode = new TestRootNode(leftChild, rightChild); + CallTarget target = runtime.createCallTarget(rootNode); + Assert.assertEquals(rootNode, leftChild.getParent()); + Assert.assertEquals(rootNode, rightChild.getParent()); + Iterator iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(leftChild, iterator.next()); + Assert.assertEquals(rightChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(42, result); + } + + class TestRootNode extends RootNode { + + @Child private TestChildNode left; + @Child private TestChildNode right; + + public TestRootNode(TestChildNode left, TestChildNode right) { + super(TestingLanguage.class, null, null); + this.left = left; + this.right = right; + } + + @Override + public Object execute(VirtualFrame frame) { + return left.execute() + right.execute(); + } + } + + class TestChildNode extends Node { + + public TestChildNode() { + super(null); + } + + public int execute() { + return 21; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ChildrenNodesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ChildrenNodesTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Creating an Array of Children Nodes

+ * + *

+ * An array of children nodes can be used as a field in a parent node. The field has to be annotated + * with {@link com.oracle.truffle.api.nodes.Node.Children} and must be declared private and final. + * Before assigning the field in the parent node constructor, {@link Node#adoptChildren} must be + * called in order to update the parent pointers in the child nodes. After filling the array with + * its first values, it must never be changed. It is only possible to call {@link Node#replace} on a + * child node. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.FinalFieldTest}. + *

+ */ +public class ChildrenNodesTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildNode firstChild = new TestChildNode(); + TestChildNode secondChild = new TestChildNode(); + TestRootNode rootNode = new TestRootNode(new TestChildNode[]{firstChild, secondChild}); + CallTarget target = runtime.createCallTarget(rootNode); + Assert.assertEquals(rootNode, firstChild.getParent()); + Assert.assertEquals(rootNode, secondChild.getParent()); + Iterator iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(firstChild, iterator.next()); + Assert.assertEquals(secondChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(42, result); + } + + class TestRootNode extends RootNode { + + @Children private final TestChildNode[] children; + + public TestRootNode(TestChildNode[] children) { + super(TestingLanguage.class, null, null); + this.children = children; + } + + @Override + public Object execute(VirtualFrame frame) { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].execute(); + } + return sum; + } + } + + class TestChildNode extends Node { + + public TestChildNode() { + super(null); + } + + public int execute() { + return 21; + } + } + + @Test + public void testMultipleChildrenFields() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildNode firstChild = new TestChildNode(); + TestChildNode secondChild = new TestChildNode(); + TestChildNode thirdChild = new TestChildNode(); + TestChildNode forthChild = new TestChildNode(); + TestRootNode rootNode = new TestRoot2Node(new TestChildNode[]{firstChild, secondChild}, new TestChildNode[]{thirdChild, forthChild}); + CallTarget target = runtime.createCallTarget(rootNode); + Assert.assertEquals(rootNode, firstChild.getParent()); + Assert.assertEquals(rootNode, secondChild.getParent()); + Assert.assertEquals(rootNode, thirdChild.getParent()); + Assert.assertEquals(rootNode, forthChild.getParent()); + Iterator iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(firstChild, iterator.next()); + Assert.assertEquals(secondChild, iterator.next()); + Assert.assertEquals(thirdChild, iterator.next()); + Assert.assertEquals(forthChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(2 * 42, result); + } + + class TestRoot2Node extends TestRootNode { + @Children private final TestChildNode[] children1; + @Children private final TestChildNode[] children2; + + public TestRoot2Node(TestChildNode[] children1, TestChildNode[] children2) { + super(new TestChildNode[0]); + this.children1 = children1; + this.children2 = children2; + } + + @Override + public Object execute(VirtualFrame frame) { + int sum = 0; + for (int i = 0; i < children1.length; ++i) { + sum += children1[i].execute(); + } + for (int i = 0; i < children2.length; ++i) { + sum += children2[i].execute(); + } + return sum; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FinalFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FinalFieldTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Using Final Fields in Node Classes

+ * + *

+ * The usage of final fields in node classes is highly encouraged. It is beneficial for performance + * to declare every field that is not pointing to a child node as final. This gives the Truffle + * runtime an increased opportunity to optimize this node. + *

+ * + *

+ * If a node has a value which may change at run time, but will rarely do so, it is recommended to + * speculate on the field being final. This involves starting executing with a node where this field + * is final and only if this turns out to be no longer the case, the node is replaced with an + * alternative implementation of the operation (see {@link ReplaceTest}). + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.ReplaceTest}. + *

+ */ +public class FinalFieldTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestRootNode rootNode = new TestRootNode(new TestChildNode[]{new TestChildNode(20), new TestChildNode(22)}); + CallTarget target = runtime.createCallTarget(rootNode); + Object result = target.call(); + Assert.assertEquals(42, result); + } + + private static class TestRootNode extends RootNode { + + @Children private final TestChildNode[] children; + + public TestRootNode(TestChildNode[] children) { + super(TestingLanguage.class, null, null); + this.children = children; + } + + @Override + public Object execute(VirtualFrame frame) { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].execute(); + } + return sum; + } + } + + private static class TestChildNode extends Node { + + private final int value; + + public TestChildNode(int value) { + super(null); + this.value = value; + } + + public int execute() { + return value; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameSlotTypeSpecializationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameSlotTypeSpecializationTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.FrameSlotKind; +import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Specializing Frame Slot Types

+ * + *

+ * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run + * time to a more generic type if necessary. The new type of a frame slot can be set using the + * {@link FrameSlot#setKind(FrameSlotKind)} method. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.ReturnTypeSpecializationTest}. + *

+ */ +public class FrameSlotTypeSpecializationTest { + + @Before + public void setInstrumentationTestMode() { + InstrumentationTestMode.set(true); + } + + @After + public void unsetInstrumentationTestMode() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + FrameDescriptor frameDescriptor = new FrameDescriptor(); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); + Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); + Object result = target.call(); + Assert.assertEquals("42", result); + Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); + } + + class TestRootNode extends RootNode { + + @Child TestChildNode left; + @Child TestChildNode right; + + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(TestingLanguage.class, null, descriptor); + this.left = left; + this.right = right; + } + + @Override + public Object execute(VirtualFrame frame) { + left.execute(frame); + return right.execute(frame); + } + } + + abstract class TestChildNode extends Node { + + protected TestChildNode() { + super(null); + } + + abstract Object execute(VirtualFrame frame); + } + + abstract class FrameSlotNode extends TestChildNode { + + protected final FrameSlot slot; + + public FrameSlotNode(FrameSlot slot) { + this.slot = slot; + } + } + + class StringTestChildNode extends TestChildNode { + + @Override + Object execute(VirtualFrame frame) { + return "42"; + } + + } + + class IntAssignLocal extends FrameSlotNode { + + @Child private TestChildNode value; + + IntAssignLocal(FrameSlot slot, TestChildNode value) { + super(slot); + this.value = value; + } + + @Override + Object execute(VirtualFrame frame) { + Object o = value.execute(frame); + if (o instanceof Integer) { + frame.setInt(slot, (Integer) o); + } else { + slot.setKind(FrameSlotKind.Object); + frame.setObject(slot, o); + this.replace(new ObjectAssignLocal(slot, value)); + } + return null; + } + } + + class ObjectAssignLocal extends FrameSlotNode { + + @Child private TestChildNode value; + + ObjectAssignLocal(FrameSlot slot, TestChildNode value) { + super(slot); + this.value = value; + } + + @Override + Object execute(VirtualFrame frame) { + Object o = value.execute(frame); + slot.setKind(FrameSlotKind.Object); + frame.setObject(slot, o); + return null; + } + } + + class IntReadLocal extends FrameSlotNode { + + IntReadLocal(FrameSlot slot) { + super(slot); + } + + @Override + Object execute(VirtualFrame frame) { + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return this.replace(new ObjectReadLocal(slot)).execute(frame); + } + } + } + + class ObjectReadLocal extends FrameSlotNode { + + ObjectReadLocal(FrameSlot slot) { + super(slot); + } + + @Override + Object execute(VirtualFrame frame) { + try { + return frame.getObject(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameInstance; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.FrameSlotKind; +import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +/** + *

Storing Values in Frame Slots

+ * + *

+ * The frame is the preferred data structure for passing values between nodes. It can in particular + * be used for storing the values of local variables of the guest language. The + * {@link FrameDescriptor} represents the current structure of the frame. The method + * {@link FrameDescriptor#addFrameSlot(Object, FrameSlotKind)} can be used to create predefined + * frame slots. The setter and getter methods in the {@link Frame} class can be used to access the + * current value of a particular frame slot. Values can be removed from a frame via the + * {@link FrameDescriptor#removeFrameSlot(Object)} method. + *

+ * + *

+ * There are five primitive types for slots available: {@link java.lang.Boolean}, + * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float}, and + * {@link java.lang.Double} . It is encouraged to use those types whenever possible. Dynamically + * typed languages can speculate on the type of a value fitting into a primitive (see + * {@link FrameSlotTypeSpecializationTest}). When a frame slot is of one of those particular + * primitive types, its value may only be accessed with the respectively typed getter method ( + * {@link Frame#getBoolean}, {@link Frame#getInt}, {@link Frame#getLong}, {@link Frame#getFloat}, or + * {@link Frame#getDouble}) or setter method ({@link Frame#setBoolean}, {@link Frame#setInt}, + * {@link Frame#setLong}, {@link Frame#setFloat}, or {@link Frame#setDouble}) in the {@link Frame} + * class. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.FrameSlotTypeSpecializationTest}. + *

+ */ +public class FrameTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() throws SecurityException, IllegalArgumentException { + TruffleRuntime runtime = Truffle.getRuntime(); + FrameDescriptor frameDescriptor = new FrameDescriptor(); + String varName = "localVar"; + FrameSlot slot = frameDescriptor.addFrameSlot(varName, FrameSlotKind.Int); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new AssignLocal(slot), new ReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); + Object result = target.call(); + Assert.assertEquals(42, result); + frameDescriptor.removeFrameSlot(varName); + boolean slotMissing = false; + try { + result = target.call(); + } catch (IllegalArgumentException iae) { + slotMissing = true; + } + Assert.assertTrue(slotMissing); + } + + class TestRootNode extends RootNode { + + @Child TestChildNode left; + @Child TestChildNode right; + + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(TestingLanguage.class, null, descriptor); + this.left = left; + this.right = right; + } + + @Override + public Object execute(VirtualFrame frame) { + return left.execute(frame) + right.execute(frame); + } + } + + abstract class TestChildNode extends Node { + + public TestChildNode() { + super(null); + } + + abstract int execute(VirtualFrame frame); + } + + abstract class FrameSlotNode extends TestChildNode { + + protected final FrameSlot slot; + + public FrameSlotNode(FrameSlot slot) { + this.slot = slot; + } + } + + class AssignLocal extends FrameSlotNode { + + AssignLocal(FrameSlot slot) { + super(slot); + } + + @Override + int execute(VirtualFrame frame) { + frame.setInt(slot, 42); + return 0; + } + } + + class ReadLocal extends FrameSlotNode { + + ReadLocal(FrameSlot slot) { + super(slot); + } + + @Override + int execute(VirtualFrame frame) { + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } + } + } + + @Test + public void framesCanBeMaterialized() { + final TruffleRuntime runtime = Truffle.getRuntime(); + + class FrameRootNode extends RootNode { + + public FrameRootNode() { + super(TestingLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + FrameInstance frameInstance = runtime.getCurrentFrame(); + Frame readWrite = frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, true); + Frame materialized = frameInstance.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true); + + assertTrue("Really materialized: " + materialized, materialized instanceof MaterializedFrame); + assertEquals("It's my frame", frame, readWrite); + return this; + } + } + + FrameRootNode frn = new FrameRootNode(); + Object ret = Truffle.getRuntime().createCallTarget(frn).call(); + assertEquals("Returns itself", frn, ret); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/InterfaceChildFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/InterfaceChildFieldTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2014, 2014, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeInterface; +import com.oracle.truffle.api.nodes.NodeUtil; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Test child fields declared with interface types instead of {@link Node} subclasses. + */ +public class InterfaceChildFieldTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void testChild() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildInterface leftChild = new TestLeafNode(); + TestChildInterface rightChild = new TestLeafNode(); + TestChildNode parent = new TestChildNode(leftChild, rightChild); + TestRootNode rootNode = new TestRootNode(parent); + CallTarget target = runtime.createCallTarget(rootNode); + Iterator iterator = parent.getChildren().iterator(); + Assert.assertEquals(leftChild, iterator.next()); + Assert.assertEquals(rightChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(42, result); + + Assert.assertEquals(4, NodeUtil.countNodes(rootNode)); + Assert.assertEquals(4, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); + } + + @Test + public void testChildren() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildInterface[] children = new TestChildInterface[5]; + for (int i = 0; i < children.length; i++) { + children[i] = new TestLeafNode(); + } + TestChildrenNode parent = new TestChildrenNode(children); + TestRootNode rootNode = new TestRootNode(parent); + CallTarget target = runtime.createCallTarget(rootNode); + Iterator iterator = parent.getChildren().iterator(); + for (int i = 0; i < children.length; i++) { + Assert.assertEquals(children[i], iterator.next()); + } + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(105, result); + + Assert.assertEquals(2 + children.length, NodeUtil.countNodes(rootNode)); + Assert.assertEquals(2 + children.length, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); + } + + class TestRootNode extends RootNode { + + @Child private TestChildInterface child; + + public TestRootNode(TestChildInterface child) { + super(TestingLanguage.class, null, null); + this.child = child; + } + + @Override + public Object execute(VirtualFrame frame) { + return child.executeIntf(); + } + } + + interface TestChildInterface extends NodeInterface { + int executeIntf(); + } + + class TestLeafNode extends Node implements TestChildInterface { + public TestLeafNode() { + super(null); + } + + public int executeIntf() { + return this.replace(new TestLeaf2Node()).executeIntf(); + } + } + + class TestLeaf2Node extends Node implements TestChildInterface { + public TestLeaf2Node() { + super(null); + } + + public int executeIntf() { + return 21; + } + } + + class TestChildNode extends Node implements TestChildInterface { + + @Child private TestChildInterface left; + @Child private TestChildInterface right; + + public TestChildNode(TestChildInterface left, TestChildInterface right) { + super(null); + this.left = left; + this.right = right; + } + + @Override + public int executeIntf() { + return left.executeIntf() + right.executeIntf(); + } + } + + class TestChildrenNode extends Node implements TestChildInterface { + + @Children private final TestChildInterface[] children; + + public TestChildrenNode(TestChildInterface[] children) { + super(null); + this.children = children; + } + + @Override + public int executeIntf() { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].executeIntf(); + } + return sum; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ReplaceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ReplaceTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + *

Replacing Nodes at Run Time

+ * + *

+ * The structure of the Truffle tree can be changed at run time by replacing nodes using the + * {@link Node#replace(Node)} method. This method will automatically change the child pointer in the + * parent of the node and replace it with a pointer to the new node. + *

+ * + *

+ * Replacing nodes is a costly operation, so it should not happen too often. The convention is that + * the implementation of the Truffle nodes should ensure that there are maximal a small (and + * constant) number of node replacements per Truffle node. + *

+ * + *

+ * The next part of the Truffle API introduction is at {@link com.oracle.truffle.api.CallTest}. + *

+ */ +public class ReplaceTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + UnresolvedNode leftChild = new UnresolvedNode("20"); + UnresolvedNode rightChild = new UnresolvedNode("22"); + TestRootNode rootNode = new TestRootNode(new ValueNode[]{leftChild, rightChild}); + CallTarget target = runtime.createCallTarget(rootNode); + assertEquals(rootNode, leftChild.getParent()); + assertEquals(rootNode, rightChild.getParent()); + Iterator iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(leftChild, iterator.next()); + Assert.assertEquals(rightChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + assertEquals(42, result); + assertEquals(42, target.call()); + iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(ResolvedNode.class, iterator.next().getClass()); + Assert.assertEquals(ResolvedNode.class, iterator.next().getClass()); + Assert.assertFalse(iterator.hasNext()); + iterator = rootNode.getChildren().iterator(); + Assert.assertEquals(rootNode, iterator.next().getParent()); + Assert.assertEquals(rootNode, iterator.next().getParent()); + Assert.assertFalse(iterator.hasNext()); + } + + class TestRootNode extends RootNode { + + @Children private final ValueNode[] children; + + public TestRootNode(ValueNode[] children) { + super(TestingLanguage.class, null, null); + this.children = children; + } + + @Override + public Object execute(VirtualFrame frame) { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].execute(); + } + return sum; + } + } + + abstract class ValueNode extends Node { + + public ValueNode() { + super(null); + } + + abstract int execute(); + } + + class UnresolvedNode extends ValueNode { + + private final String value; + + public UnresolvedNode(String value) { + this.value = value; + } + + @Override + int execute() { + int intValue = Integer.parseInt(value); + ResolvedNode newNode = this.replace(new ResolvedNode(intValue)); + return newNode.execute(); + } + } + + class ResolvedNode extends ValueNode { + + private final int value; + + ResolvedNode(int value) { + this.value = value; + } + + @Override + int execute() { + return value; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ReturnTypeSpecializationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ReturnTypeSpecializationTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.frame.FrameSlotKind; +import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Specializing Return Types

+ * + *

+ * In order to avoid boxing and/or type casts on the return value of a node, the return value the + * method for executing a node can have a specific type and need not be of type + * {@link java.lang.Object}. For dynamically typed languages, this return type is something that + * should be speculated on. When the speculation fails and the child node cannot return the + * appropriate type of value, it can use an {@link UnexpectedResultException} to still pass the + * result to the caller. In such a case, the caller must rewrite itself to a more general version in + * order to avoid future failures of this kind. + *

+ */ +public class ReturnTypeSpecializationTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + FrameDescriptor frameDescriptor = new FrameDescriptor(); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); + Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); + Object result = target.call(); + Assert.assertEquals("42", result); + Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); + } + + class TestRootNode extends RootNode { + + @Child TestChildNode left; + @Child TestChildNode right; + + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(TestingLanguage.class, null, descriptor); + this.left = left; + this.right = right; + } + + @Override + public Object execute(VirtualFrame frame) { + left.execute(frame); + return right.execute(frame); + } + } + + abstract class TestChildNode extends Node { + + public TestChildNode() { + super(null); + } + + abstract Object execute(VirtualFrame frame); + + int executeInt(VirtualFrame frame) throws UnexpectedResultException { + Object result = execute(frame); + if (result instanceof Integer) { + return (Integer) result; + } + throw new UnexpectedResultException(result); + } + } + + abstract class FrameSlotNode extends TestChildNode { + + protected final FrameSlot slot; + + public FrameSlotNode(FrameSlot slot) { + this.slot = slot; + } + } + + class StringTestChildNode extends TestChildNode { + + @Override + Object execute(VirtualFrame frame) { + return "42"; + } + + } + + class IntAssignLocal extends FrameSlotNode { + + @Child private TestChildNode value; + + IntAssignLocal(FrameSlot slot, TestChildNode value) { + super(slot); + this.value = value; + } + + @Override + Object execute(VirtualFrame frame) { + try { + int result = value.executeInt(frame); + frame.setInt(slot, result); + } catch (UnexpectedResultException e) { + slot.setKind(FrameSlotKind.Object); + frame.setObject(slot, e.getResult()); + replace(new ObjectAssignLocal(slot, value)); + } + return null; + } + } + + class ObjectAssignLocal extends FrameSlotNode { + + @Child private TestChildNode value; + + ObjectAssignLocal(FrameSlot slot, TestChildNode value) { + super(slot); + this.value = value; + } + + @Override + Object execute(VirtualFrame frame) { + Object o = value.execute(frame); + slot.setKind(FrameSlotKind.Object); + frame.setObject(slot, o); + return null; + } + } + + class IntReadLocal extends FrameSlotNode { + + IntReadLocal(FrameSlot slot) { + super(slot); + } + + @Override + Object execute(VirtualFrame frame) { + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return replace(new ObjectReadLocal(slot)).execute(frame); + } + } + + @Override + int executeInt(VirtualFrame frame) throws UnexpectedResultException { + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return replace(new ObjectReadLocal(slot)).executeInt(frame); + } + } + } + + class ObjectReadLocal extends FrameSlotNode { + + ObjectReadLocal(FrameSlot slot) { + super(slot); + } + + @Override + Object execute(VirtualFrame frame) { + try { + return frame.getObject(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/RootNodeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/RootNodeTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2012, 2013, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

Creating a Root Node

+ * + *

+ * A Truffle root node is the entry point into a Truffle tree that represents a guest language + * method. It contains a {@link RootNode#execute(VirtualFrame)} method that can return a + * {@link java.lang.Object} value as the result of the guest language method invocation. This method + * must however never be called directly. Instead, the Truffle runtime must be used to create a + * {@link CallTarget} object from a root node using the + * {@link TruffleRuntime#createCallTarget(RootNode)} method. This call target object can then be + * executed using the {@link CallTarget#call(Object...)} method or one of its overloads. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.ChildNodeTest}. + *

+ */ +public class RootNodeTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void test() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestRootNode rootNode = new TestRootNode(); + CallTarget target = runtime.createCallTarget(rootNode); + Object result = target.call(); + Assert.assertEquals(42, result); + } + + class TestRootNode extends RootNode { + + public TestRootNode() { + super(TestingLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + return 42; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/TestingLanguage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/TestingLanguage.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 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; + +import java.io.IOException; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; + +public final class TestingLanguage extends TruffleLanguage { + public static final TestingLanguage INSTANCE = new TestingLanguage(); + + private TestingLanguage() { + } + + @Override + protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { + throw new IOException(); + } + + @Override + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Object context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected boolean isInstrumentable(Node node) { + return false; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + return null; + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + return null; + } + + @Override + protected Object createContext(Env env) { + return null; + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ThreadSafetyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/ThreadSafetyTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2014, 2014, 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; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeUtil; +import com.oracle.truffle.api.nodes.RootNode; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Test node rewriting in a tree shared across multiple threads (run with -ea). + */ +public class ThreadSafetyTest { + + @Test + @Ignore("sporadic failures with \"expected:<1000000> but was:<999999>\"") + public void test() throws InterruptedException { + TruffleRuntime runtime = Truffle.getRuntime(); + TestRootNode rootNode1 = new TestRootNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new ConstNode(42))))))); + final CallTarget target1 = runtime.createCallTarget(rootNode1); + NodeUtil.verify(rootNode1); + + RecursiveCallNode callNode = new RecursiveCallNode(new ConstNode(42)); + TestRootNode rootNode2 = new TestRootNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(callNode)))))); + final CallTarget target2 = runtime.createCallTarget(rootNode2); + callNode.setCallNode(runtime.createDirectCallNode(target2)); + NodeUtil.verify(rootNode2); + + testTarget(target1, 47, 1_000_000); + testTarget(target2, 72, 1_000_000); + } + + private static void testTarget(final CallTarget target, final int expectedResult, final int numberOfIterations) throws InterruptedException { + ExecutorService executorService = Executors.newFixedThreadPool(20); + final AtomicInteger ai = new AtomicInteger(); + for (int i = 0; i < numberOfIterations; i++) { + executorService.submit(new Runnable() { + public void run() { + try { + Object result = target.call(new Object[]{5}); + assertEquals(expectedResult, result); + ai.incrementAndGet(); + } catch (Throwable t) { + t.printStackTrace(System.out); + } + } + }); + } + executorService.shutdown(); + executorService.awaitTermination(90, TimeUnit.SECONDS); + assertTrue("test did not terminate", executorService.isTerminated()); + assertEquals(numberOfIterations, ai.get()); + } + + static class TestRootNode extends RootNode { + + @Child private ValueNode child; + + public TestRootNode(ValueNode child) { + super(TestingLanguage.class, null, null); + this.child = child; + } + + @Override + public Object execute(VirtualFrame frame) { + return child.execute(frame); + } + } + + abstract static class ValueNode extends Node { + + public ValueNode() { + super(null); + } + + abstract int execute(VirtualFrame frame); + } + + static class RewritingNode extends ValueNode { + + @Child private ValueNode child; + private final Random random; + + public RewritingNode(ValueNode child) { + this(child, new Random()); + } + + public RewritingNode(ValueNode child, Random random) { + this.child = child; + this.random = random; + } + + @Override + int execute(VirtualFrame frame) { + boolean replace = random.nextBoolean(); + if (replace) { + ValueNode newNode = this.replace(new OtherRewritingNode(child, random)); + return newNode.execute(frame); + } + return 1 + child.execute(frame); + } + } + + static class OtherRewritingNode extends ValueNode { + + @Child private ValueNode child; + private final Random random; + + public OtherRewritingNode(ValueNode child, Random random) { + this.child = child; + this.random = random; + } + + @Override + int execute(VirtualFrame frame) { + boolean replace = random.nextBoolean(); + if (replace) { + ValueNode newNode = this.replace(new RewritingNode(child, random)); + return newNode.execute(frame); + } + return 1 + child.execute(frame); + } + } + + static class ConstNode extends ValueNode { + + private final int value; + + ConstNode(int value) { + this.value = value; + } + + @Override + int execute(VirtualFrame frame) { + return value; + } + } + + static class RecursiveCallNode extends ValueNode { + @Child DirectCallNode callNode; + @Child private ValueNode valueNode; + + RecursiveCallNode(ValueNode value) { + this.valueNode = value; + } + + @Override + int execute(VirtualFrame frame) { + int arg = (Integer) frame.getArguments()[0]; + if (arg > 0) { + return (int) callNode.call(frame, new Object[]{(arg - 1)}); + } else { + return valueNode.execute(frame); + } + } + + void setCallNode(DirectCallNode callNode) { + this.callNode = insert(callNode); + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/TruffleRuntimeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/TruffleRuntimeTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.NodeUtil; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +/** + *

Accessing the Truffle Runtime

+ * + *

+ * The Truffle runtime can be accessed at any point in time globally using the static method + * {@link Truffle#getRuntime()}. This method is guaranteed to return a non-null Truffle runtime + * object with an identifying name. A Java Virtual Machine implementation can chose to replace the + * default implementation of the {@link TruffleRuntime} interface with its own implementation for + * providing improved performance. + *

+ * + *

+ * The next part of the Truffle API introduction is at + * {@link com.oracle.truffle.api.RootNodeTest}. + *

+ */ +public class TruffleRuntimeTest { + + private TruffleRuntime runtime; + + @Before + public void before() { + InstrumentationTestMode.set(true); + this.runtime = Truffle.getRuntime(); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + private static RootNode createTestRootNode(SourceSection sourceSection) { + return new RootNode(TestingLanguage.class, sourceSection, null) { + @Override + public Object execute(VirtualFrame frame) { + return 42; + } + }; + } + + // @Test + public void verifyTheRealRuntimeIsUsedOnRealGraal() { + TruffleRuntime r = Truffle.getRuntime(); + final String name = r.getClass().getName(); + if (name.endsWith("DefaultTruffleRuntime")) { + fail("Wrong name " + name + " with following System.getProperties:\n" + System.getProperties().toString()); + } + } + + @Test + public void test() { + assertNotNull(runtime); + assertNotNull(runtime.getName()); + } + + @Test + public void testCreateCallTarget() { + RootNode rootNode = createTestRootNode(null); + RootCallTarget target = runtime.createCallTarget(rootNode); + assertNotNull(target); + assertEquals(target.call(), 42); + assertSame(rootNode, target.getRootNode()); + } + + @Test + public void testGetCallTargets1() { + RootNode rootNode = createTestRootNode(null); + RootCallTarget target = runtime.createCallTarget(rootNode); + assertTrue(runtime.getCallTargets().contains(target)); + } + + @Test + public void testGetCallTargets2() { + RootNode rootNode = createTestRootNode(null); + RootCallTarget target1 = runtime.createCallTarget(rootNode); + RootCallTarget target2 = runtime.createCallTarget(rootNode); + assertTrue(runtime.getCallTargets().contains(target1)); + assertTrue(runtime.getCallTargets().contains(target2)); + } + + /* + * This test case documents the use case for profilers and debuggers where they need to access + * multiple call targets for the same source section. This case may happen when the optimization + * system decides to duplicate call targets to achieve better performance. + */ + @Test + public void testGetCallTargets3() { + Source source1 = Source.fromText("a\nb\n", ""); + SourceSection sourceSection1 = source1.createSection("foo", 1); + SourceSection sourceSection2 = source1.createSection("bar", 2); + + RootNode rootNode1 = createTestRootNode(sourceSection1); + RootNode rootNode2 = createTestRootNode(sourceSection2); + RootNode rootNode2Copy = NodeUtil.cloneNode(rootNode2); + + assertSame(rootNode2.getSourceSection(), rootNode2Copy.getSourceSection()); + + RootCallTarget target1 = runtime.createCallTarget(rootNode1); + RootCallTarget target2 = runtime.createCallTarget(rootNode2); + RootCallTarget target2Copy = runtime.createCallTarget(rootNode2Copy); + + Map> groupedTargets = groupUniqueCallTargets(); + + List targets1 = groupedTargets.get(sourceSection1); + assertEquals(1, targets1.size()); + assertEquals(target1, targets1.get(0)); + + List targets2 = groupedTargets.get(sourceSection2); + assertEquals(2, targets2.size()); + // order of targets2 is not guaranteed + assertTrue(target2 == targets2.get(0) ^ target2Copy == targets2.get(0)); + assertTrue(target2 == targets2.get(1) ^ target2Copy == targets2.get(1)); + } + + private static Map> groupUniqueCallTargets() { + Map> groupedTargets = new HashMap<>(); + for (RootCallTarget target : Truffle.getRuntime().getCallTargets()) { + SourceSection section = target.getRootNode().getSourceSection(); + if (section == null) { + // can not identify root node to a unique call target. Print warning? + continue; + } + List targets = groupedTargets.get(section); + if (targets == null) { + targets = new ArrayList<>(); + groupedTargets.put(section, targets); + } + targets.add(target); + } + return groupedTargets; + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/EvalInstrumentTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/EvalInstrumentTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015, 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.instrument; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.EvalInstrumentListener; +import com.oracle.truffle.api.instrument.Instrument; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.SyntaxTag; +import com.oracle.truffle.api.instrument.InstrumentationTestingLanguage.InstrumentTestTag; +import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; + +/** + * Tests the kind of instrumentation where a client can provide guest language code to be + * spliced directly into the AST. + */ +public class EvalInstrumentTest { + + PolyglotEngine vm; + Instrumenter instrumenter; + + @Before + public void before() { + // TODO (mlvdv) eventually abstract this + try { + vm = PolyglotEngine.newBuilder().build(); + final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + instrumenter = (Instrumenter) field.get(vm); + final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); + testVMField.setAccessible(true); + testVMField.set(instrumenter, vm); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + fail("Reflective access to Instrumenter for testing"); + } + } + + @After + public void after() { + vm.dispose(); + vm = null; + instrumenter = null; + } + + @Test + public void testEvalInstrumentListener() throws IOException { + + instrumenter.registerASTProber(new InstrumentationTestingLanguage.TestASTProber()); + final Source source13 = InstrumentationTestingLanguage.createAdditionSource13("testEvalInstrumentListener"); + + final Probe[] addNodeProbe = new Probe[1]; + instrumenter.addProbeListener(new DefaultProbeListener() { + + @Override + public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { + if (tag == InstrumentTestTag.ADD_TAG) { + addNodeProbe[0] = probe; + } + } + }); + assertEquals(vm.eval(source13).get(), 13); + assertNotNull("Add node should be probed", addNodeProbe[0]); + + final Source source42 = InstrumentationTestingLanguage.createConstantSource42("testEvalInstrumentListener"); + final int[] evalResult = {0}; + final int[] evalCount = {0}; + final Instrument instrument = instrumenter.attach(addNodeProbe[0], source42, new EvalInstrumentListener() { + + public void onExecution(Node node, VirtualFrame vFrame, Object result) { + evalCount[0] = evalCount[0] + 1; + if (result instanceof Integer) { + evalResult[0] = (Integer) result; + } + } + + public void onFailure(Node node, VirtualFrame vFrame, Exception ex) { + fail("Eval test evaluates without exception"); + + } + }, "test EvalInstrument", null); + + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 1); + assertEquals(evalResult[0], 42); + + // Second execution; same result + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 2); + assertEquals(evalResult[0], 42); + + // Add new eval instrument with no listener, no effect on third execution + instrumenter.attach(addNodeProbe[0], source42, null, "", null); + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 3); + assertEquals(evalResult[0], 42); + + // Remove original instrument; no further effect from fourth execution + instrument.dispose(); + evalResult[0] = 0; + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 3); + assertEquals(evalResult[0], 0); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2014, 2015, 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.instrument; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.Test; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.ASTProber; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.ProbeInstrument; +import com.oracle.truffle.api.instrument.SimpleInstrumentListener; +import com.oracle.truffle.api.instrument.StandardInstrumentListener; +import com.oracle.truffle.api.instrument.SyntaxTag; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestAdditionNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestLanguageNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestValueNode; +import com.oracle.truffle.api.instrument.InstrumentationTestingLanguage.InstrumentTestTag; +import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; +import com.oracle.truffle.api.instrument.impl.DefaultSimpleInstrumentListener; +import com.oracle.truffle.api.instrument.impl.DefaultStandardInstrumentListener; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeVisitor; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; + +/** + *

AST Instrumentation

+ * + * Instrumentation allows the insertion into Truffle ASTs language-specific instances of + * {@link WrapperNode} that propagate execution events through a {@link Probe} to any instances of + * {@link ProbeInstrument} that might be attached to the particular probe by tools. + */ +public class InstrumentationTest { + + @Test + public void testProbing() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); + final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + instrumenter.registerASTProber(new TestASTProber(instrumenter)); + final Source source = InstrumentationTestingLanguage.createAdditionSource13("testProbing"); + + final Probe[] probes = new Probe[3]; + instrumenter.addProbeListener(new DefaultProbeListener() { + + @Override + public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { + if (tag == InstrumentTestTag.ADD_TAG) { + assertEquals(probes[0], null); + probes[0] = probe; + } else if (tag == InstrumentTestTag.VALUE_TAG) { + if (probes[1] == null) { + probes[1] = probe; + } else if (probes[2] == null) { + probes[2] = probe; + } else { + fail("Should only be three probes"); + } + } + } + }); + assertEquals(vm.eval(source).get(), 13); + assertNotNull("Add node should be probed", probes[0]); + assertNotNull("Value nodes should be probed", probes[1]); + assertNotNull("Value nodes should be probed", probes[2]); + // Check instrumentation with the simplest kind of counters. + // They should all be removed when the check is finished. + checkCounters(probes[0], vm, source, new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter)); + + // Now try with the more complex flavor of listener + checkCounters(probes[0], vm, source, new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter)); + + } + + @Test + public void testTagging() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + + final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); + final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + final Source source = InstrumentationTestingLanguage.createAdditionSource13("testTagging"); + + // Applies appropriate tags + final TestASTProber astProber = new TestASTProber(instrumenter); + instrumenter.registerASTProber(astProber); + + // Listens for probes and tags being added + final TestProbeListener probeListener = new TestProbeListener(); + instrumenter.addProbeListener(probeListener); + + assertEquals(13, vm.eval(source).get()); + + // Check that the prober added probes to the tree + assertEquals(probeListener.probeCount, 3); + assertEquals(probeListener.tagCount, 3); + + assertEquals(instrumenter.findProbesTaggedAs(InstrumentTestTag.ADD_TAG).size(), 1); + assertEquals(instrumenter.findProbesTaggedAs(InstrumentTestTag.VALUE_TAG).size(), 2); + } + + private static void checkCounters(Probe probe, PolyglotEngine vm, Source source, TestCounter counterA, TestCounter counterB, TestCounter counterC) throws IOException { + + // Attach a counting instrument to the probe + counterA.attach(probe); + + // Attach a second counting instrument to the probe + counterB.attach(probe); + + // Run it again and check that the two instruments are working + assertEquals(13, vm.eval(source).get()); + assertEquals(counterA.enterCount(), 1); + assertEquals(counterA.leaveCount(), 1); + assertEquals(counterB.enterCount(), 1); + assertEquals(counterB.leaveCount(), 1); + + // Remove counterA + counterA.dispose(); + + // Run it again and check that instrument B is still working but not A + assertEquals(13, vm.eval(source).get()); + assertEquals(counterA.enterCount(), 1); + assertEquals(counterA.leaveCount(), 1); + assertEquals(counterB.enterCount(), 2); + assertEquals(counterB.leaveCount(), 2); + + // Attach a second instrument to the probe + counterC.attach(probe); + + // Run the original and check that instruments B,C working but not A + assertEquals(13, vm.eval(source).get()); + assertEquals(counterA.enterCount(), 1); + assertEquals(counterA.leaveCount(), 1); + assertEquals(counterB.enterCount(), 3); + assertEquals(counterB.leaveCount(), 3); + assertEquals(counterC.enterCount(), 1); + assertEquals(counterC.leaveCount(), 1); + + // Remove instrumentC + counterC.dispose(); + + // Run the original and check that instrument B working but not A,C + assertEquals(13, vm.eval(source).get()); + assertEquals(counterA.enterCount(), 1); + assertEquals(counterA.leaveCount(), 1); + assertEquals(counterB.enterCount(), 4); + assertEquals(counterB.leaveCount(), 4); + assertEquals(counterC.enterCount(), 1); + assertEquals(counterC.leaveCount(), 1); + + // Remove instrumentB + counterB.dispose(); + + // Check that no instruments working + assertEquals(13, vm.eval(source).get()); + assertEquals(counterA.enterCount(), 1); + assertEquals(counterA.leaveCount(), 1); + assertEquals(counterB.enterCount(), 4); + assertEquals(counterB.leaveCount(), 4); + assertEquals(counterC.enterCount(), 1); + assertEquals(counterC.leaveCount(), 1); + } + + private interface TestCounter { + + int enterCount(); + + int leaveCount(); + + void attach(Probe probe); + + void dispose(); + } + + /** + * A counter for the number of times execution enters and leaves a probed AST node. + */ + private class TestSimpleInstrumentCounter implements TestCounter { + + public int enterCount = 0; + public int leaveCount = 0; + public Instrumenter instrumenter; + private ProbeInstrument instrument; + + public TestSimpleInstrumentCounter(Instrumenter instrumenter) { + this.instrumenter = instrumenter; + } + + @Override + public int enterCount() { + return enterCount; + } + + @Override + public int leaveCount() { + return leaveCount; + } + + @Override + public void attach(Probe probe) { + instrument = instrumenter.attach(probe, new SimpleInstrumentListener() { + + public void onEnter(Probe p) { + enterCount++; + } + + public void onReturnVoid(Probe p) { + leaveCount++; + } + + public void onReturnValue(Probe p, Object result) { + leaveCount++; + } + + public void onReturnExceptional(Probe p, Throwable exception) { + leaveCount++; + } + }, "Instrumentation Test Counter"); + } + + @Override + public void dispose() { + instrument.dispose(); + } + } + + /** + * A counter for the number of times execution enters and leaves a probed AST node. + */ + private class TestStandardInstrumentCounter implements TestCounter { + + public int enterCount = 0; + public int leaveCount = 0; + public final Instrumenter instrumenter; + public ProbeInstrument instrument; + + public TestStandardInstrumentCounter(Instrumenter instrumenter) { + this.instrumenter = instrumenter; + } + + @Override + public int enterCount() { + return enterCount; + } + + @Override + public int leaveCount() { + return leaveCount; + } + + @Override + public void attach(Probe probe) { + instrument = instrumenter.attach(probe, new StandardInstrumentListener() { + + public void onEnter(Probe p, Node node, VirtualFrame vFrame) { + enterCount++; + } + + public void onReturnVoid(Probe p, Node node, VirtualFrame vFrame) { + leaveCount++; + } + + public void onReturnValue(Probe p, Node node, VirtualFrame vFrame, Object result) { + leaveCount++; + } + + public void onReturnExceptional(Probe p, Node node, VirtualFrame vFrame, Throwable exception) { + leaveCount++; + } + }, "Instrumentation Test Counter"); + } + + @Override + public void dispose() { + instrument.dispose(); + } + } + + /** + * Tags selected nodes on newly constructed ASTs. + */ + private static final class TestASTProber implements NodeVisitor, ASTProber { + + private final Instrumenter instrumenter; + + TestASTProber(Instrumenter instrumenter) { + this.instrumenter = instrumenter; + } + + @Override + public boolean visit(Node node) { + if (node instanceof TestLanguageNode) { + + final TestLanguageNode testNode = (TestLanguageNode) node; + + if (node instanceof TestValueNode) { + instrumenter.probe(testNode).tagAs(InstrumentTestTag.VALUE_TAG, null); + + } else if (node instanceof TestAdditionNode) { + instrumenter.probe(testNode).tagAs(InstrumentTestTag.ADD_TAG, null); + + } + } + return true; + } + + @Override + public void probeAST(Instrumenter inst, RootNode rootNode) { + rootNode.accept(this); + } + } + + /** + * Counts the number of "enter" events at probed nodes using the simplest AST listener. + */ + static final class TestSimpleInstrumentListener extends DefaultSimpleInstrumentListener { + + public int counter = 0; + + @Override + public void onEnter(Probe probe) { + counter++; + } + } + + /** + * Counts the number of "enter" events at probed nodes using the AST listener. + */ + static final class TestASTInstrumentListener extends DefaultStandardInstrumentListener { + + public int counter = 0; + + @Override + public void onEnter(Probe probe, Node node, VirtualFrame vFrame) { + counter++; + } + } + + private static final class TestProbeListener extends DefaultProbeListener { + + public int probeCount = 0; + public int tagCount = 0; + + @Override + public void newProbeInserted(Probe probe) { + probeCount++; + } + + @Override + public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { + tagCount++; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTestNodes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTestNodes.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014, 2015, 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.instrument; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.EventHandlerNode; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.nodes.RootNode; + +/** + * Tests instrumentation where a client can attach a node that gets attached into the AST. + */ +class InstrumentationTestNodes { + + abstract static class TestLanguageNode extends Node { + public abstract Object execute(VirtualFrame vFrame); + + } + + @NodeInfo(cost = NodeCost.NONE) + static class TestLanguageWrapperNode extends TestLanguageNode implements WrapperNode { + @Child private TestLanguageNode child; + @Child private EventHandlerNode eventHandlerNode; + + public TestLanguageWrapperNode(TestLanguageNode child) { + assert !(child instanceof TestLanguageWrapperNode); + this.child = child; + } + + @Override + public String instrumentationInfo() { + return "Wrapper node for testing"; + } + + @Override + public void insertEventHandlerNode(EventHandlerNode eventHandler) { + this.eventHandlerNode = eventHandler; + } + + @Override + public Probe getProbe() { + return eventHandlerNode.getProbe(); + } + + @Override + public Node getChild() { + return child; + } + + @Override + public Object execute(VirtualFrame vFrame) { + eventHandlerNode.enter(child, vFrame); + Object result; + try { + result = child.execute(vFrame); + eventHandlerNode.returnValue(child, vFrame, result); + } catch (Exception e) { + eventHandlerNode.returnExceptional(child, vFrame, e); + throw (e); + } + return result; + } + } + + /** + * A simple node for our test language to store a value. + */ + static class TestValueNode extends TestLanguageNode { + private final int value; + + public TestValueNode(int value) { + this.value = value; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return new Integer(this.value); + } + } + + /** + * A node for our test language that adds up two {@link TestValueNode}s. + */ + static class TestAdditionNode extends TestLanguageNode { + @Child private TestLanguageNode leftChild; + @Child private TestLanguageNode rightChild; + + public TestAdditionNode(TestValueNode leftChild, TestValueNode rightChild) { + this.leftChild = insert(leftChild); + this.rightChild = insert(rightChild); + } + + @Override + public Object execute(VirtualFrame vFrame) { + return new Integer(((Integer) leftChild.execute(vFrame)).intValue() + ((Integer) rightChild.execute(vFrame)).intValue()); + } + } + + /** + * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST + * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle + * completes an AST. The root nodes serves as our entry point into a program. + */ + static class InstrumentationTestRootNode extends RootNode { + @Child private TestLanguageNode body; + + /** + * This constructor emulates the global machinery that applies registered probers to every + * newly created AST. Global registry is not used, since that would interfere with other + * tests run in the same environment. + */ + public InstrumentationTestRootNode(TestLanguageNode body) { + super(InstrumentationTestingLanguage.class, null, null); + this.body = body; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return body.execute(vFrame); + } + + @Override + public boolean isCloningAllowed() { + return true; + } + } + + /** + * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST + * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle + * completes an AST. The root nodes serves as our entry point into a program. + */ + static class TestRootNode extends RootNode { + @Child private TestLanguageNode body; + + final Instrumenter instrumenter; + + /** + * This constructor emulates the global machinery that applies registered probers to every + * newly created AST. Global registry is not used, since that would interfere with other + * tests run in the same environment. + */ + public TestRootNode(TestLanguageNode body, Instrumenter instrumenter) { + super(InstrumentationTestingLanguage.class, null, null); + this.instrumenter = instrumenter; + this.body = body; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return body.execute(vFrame); + } + + @Override + public boolean isCloningAllowed() { + return true; + } + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTestingLanguage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/instrument/InstrumentationTestingLanguage.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2014, 2015, 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.instrument; + +import java.io.IOException; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.instrument.ASTProber; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.SyntaxTag; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.InstrumentationTestRootNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestAdditionNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestLanguageNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestLanguageWrapperNode; +import com.oracle.truffle.api.instrument.InstrumentationTestNodes.TestValueNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeVisitor; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; + +@TruffleLanguage.Registration(name = "instrumentationTestLanguage", version = "0", mimeType = "text/x-instTest") +public final class InstrumentationTestingLanguage extends TruffleLanguage { + + public static final InstrumentationTestingLanguage INSTANCE = new InstrumentationTestingLanguage(); + + private static final String ADD_SOURCE_TEXT = "Fake source text for testing: parses to 6 + 7"; + private static final String CONSTANT_SOURCE_TEXT = "Fake source text for testing: parses to 42"; + + /** Use a unique test name to avoid unexpected CallTarget sharing. */ + static Source createAdditionSource13(String testName) { + return Source.fromText(ADD_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); + } + + /** Use a unique test name to avoid unexpected CallTarget sharing. */ + static Source createConstantSource42(String testName) { + return Source.fromText(CONSTANT_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); + } + + static enum InstrumentTestTag implements SyntaxTag { + + ADD_TAG("addition", "test language addition node"), + + VALUE_TAG("value", "test language value node"); + + private final String name; + private final String description; + + private InstrumentTestTag(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + } + + private InstrumentationTestingLanguage() { + } + + @Override + protected CallTarget parse(Source source, Node context, String... argumentNames) throws IOException { + if (source.getCode().equals(ADD_SOURCE_TEXT)) { + final TestValueNode leftValueNode = new TestValueNode(6); + final TestValueNode rightValueNode = new TestValueNode(7); + final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); + final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); + final TruffleRuntime runtime = Truffle.getRuntime(); + final CallTarget callTarget = runtime.createCallTarget(rootNode); + return callTarget; + } + if (source.getCode().equals(CONSTANT_SOURCE_TEXT)) { + final TestValueNode constantNode = new TestValueNode(42); + final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(constantNode); + final TruffleRuntime runtime = Truffle.getRuntime(); + final CallTarget callTarget = runtime.createCallTarget(rootNode); + return callTarget; + } + return null; + } + + @Override + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Object context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected boolean isInstrumentable(Node node) { + return node instanceof TestAdditionNode || node instanceof TestValueNode; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + if (isInstrumentable(node)) { + return new TestLanguageWrapperNode((TestLanguageNode) node); + } + return null; + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + return null; + } + + @Override + protected Object createContext(Env env) { + return null; + } + + static final class TestASTProber implements ASTProber { + + public void probeAST(final Instrumenter instrumenter, RootNode startNode) { + startNode.accept(new NodeVisitor() { + + @Override + public boolean visit(Node node) { + if (node instanceof TestLanguageNode) { + + final TestLanguageNode testNode = (TestLanguageNode) node; + + if (node instanceof TestValueNode) { + instrumenter.probe(testNode).tagAs(InstrumentTestTag.VALUE_TAG, null); + + } else if (node instanceof TestAdditionNode) { + instrumenter.probe(testNode).tagAs(InstrumentTestTag.ADD_TAG, null); + + } + } + return true; + } + }); + } + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012, 2015, 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.interop; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import org.junit.After; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; + +public class ForeignAccessSingleThreadedTest implements ForeignAccess.Factory, TruffleObject { + ForeignAccess fa; + private int cnt; + + @Before + public void initInDifferentThread() throws InterruptedException { + Thread t = new Thread("Initializer") { + @Override + public void run() { + fa = ForeignAccess.create(ForeignAccessSingleThreadedTest.this); + } + }; + t.start(); + t.join(); + } + + @Test(expected = AssertionError.class) + public void accessNodeFromWrongThread() { + Node n = Message.IS_EXECUTABLE.createNode(); + Object ret = ForeignAccess.execute(n, null, this); + fail("Should throw an exception: " + ret); + } + + @After + public void noCallsToFactory() { + assertEquals("No calls to accessMessage or canHandle", 0, cnt); + } + + @Override + public boolean canHandle(TruffleObject obj) { + cnt++; + return true; + } + + @Override + public CallTarget accessMessage(Message tree) { + cnt++; + return null; + } + + @Override + public ForeignAccess getForeignAccess() { + return fa; + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessToStringTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessToStringTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012, 2015, 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.interop; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class ForeignAccessToStringTest { + @Test + public void checkRegularFactory() { + ForeignAccess fa = ForeignAccess.create(new SimpleTestingFactory()); + assertEquals("ForeignAccess[com.oracle.truffle.api.test.interop.ForeignAccessToStringTest$SimpleTestingFactory]", fa.toString()); + } + + @Test + public void check10Factory() { + ForeignAccess fa = ForeignAccess.create(TruffleObject.class, new Simple10TestingFactory()); + assertEquals("ForeignAccess[com.oracle.truffle.api.test.interop.ForeignAccessToStringTest$Simple10TestingFactory]", fa.toString()); + } + + private static class SimpleTestingFactory implements ForeignAccess.Factory { + public SimpleTestingFactory() { + } + + @Override + public boolean canHandle(TruffleObject obj) { + return false; + } + + @Override + public CallTarget accessMessage(Message tree) { + return null; + } + } + + private static class Simple10TestingFactory implements ForeignAccess.Factory10 { + @Override + public CallTarget accessIsNull() { + return null; + } + + @Override + public CallTarget accessIsExecutable() { + return null; + } + + @Override + public CallTarget accessIsBoxed() { + return null; + } + + @Override + public CallTarget accessHasSize() { + return null; + } + + @Override + public CallTarget accessGetSize() { + return null; + } + + @Override + public CallTarget accessUnbox() { + return null; + } + + @Override + public CallTarget accessRead() { + return null; + } + + @Override + public CallTarget accessWrite() { + return null; + } + + @Override + public CallTarget accessExecute(int argumentsLength) { + return null; + } + + @Override + public CallTarget accessInvoke(int argumentsLength) { + return null; + } + + @Override + public CallTarget accessMessage(Message unknown) { + return null; + } + + @Override + public CallTarget accessNew(int argumentsLength) { + return null; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/MessageStringTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/MessageStringTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, 2015, 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.interop; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Locale; + +import org.junit.Test; + +import com.oracle.truffle.api.interop.Message; + +public class MessageStringTest { + + @Test + public void testFields() throws Exception { + for (Field f : Message.class.getFields()) { + if (f.getType() != Message.class) { + continue; + } + if ((f.getModifiers() & Modifier.STATIC) == 0) { + continue; + } + Message msg = (Message) f.get(null); + + String persistent = Message.toString(msg); + assertNotNull("Found name for " + f, persistent); + assertEquals("It is in upper case", persistent, persistent.toUpperCase(Locale.ENGLISH)); + + Message newMsg = Message.valueOf(persistent); + + assertSame("Same for " + f, msg, newMsg); + + assertEquals("Same toString()", persistent, msg.toString()); + } + } + + @Test + public void testFactoryMethods() throws Exception { + for (Method m : Message.class.getMethods()) { + if (m.getReturnType() != Message.class) { + continue; + } + if (!m.getName().startsWith("create")) { + continue; + } + if ((m.getModifiers() & Modifier.STATIC) == 0) { + continue; + } + Message msg = (Message) m.invoke(null, 0); + + String persistent = Message.toString(msg); + assertNotNull("Found name for " + m, persistent); + assertEquals("It is in upper case", persistent, persistent.toUpperCase(Locale.ENGLISH)); + + Message newMsg = Message.valueOf(persistent); + + assertEquals("Same for " + m, msg, newMsg); + + assertEquals("Same toString()", persistent, msg.toString()); + assertEquals("Same toString() for new one", persistent, newMsg.toString()); + } + } + + @Test + public void specialMessagePersitance() { + SpecialMsg msg = new SpecialMsg(); + String persistent = Message.toString(msg); + Message newMsg = Message.valueOf(persistent); + assertEquals("Message reconstructed", msg, newMsg); + } + + public static final class SpecialMsg extends Message { + + @Override + public boolean equals(Object message) { + return message instanceof SpecialMsg; + } + + @Override + public int hashCode() { + return 5425432; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/nodes/NodeUtilTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/nodes/NodeUtilTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 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.nodes; + +import com.oracle.truffle.api.TestingLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeUtil; +import com.oracle.truffle.api.nodes.RootNode; + +import java.util.Iterator; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +public class NodeUtilTest { + + @Test + public void testRecursiveIterator1() { + TestRootNode root = new TestRootNode(); + root.child0 = new TestNode(); + root.adoptChildren(); + + int count = iterate(NodeUtil.makeRecursiveIterator(root)); + + assertThat(count, is(2)); + assertThat(root.visited, is(0)); + assertThat(root.child0.visited, is(1)); + } + + private static int iterate(Iterator iterator) { + int iterationCount = 0; + while (iterator.hasNext()) { + Node node = iterator.next(); + if (node == null) { + continue; + } + if (node instanceof TestNode) { + ((TestNode) node).visited = iterationCount; + } else if (node instanceof TestRootNode) { + ((TestRootNode) node).visited = iterationCount; + } else { + throw new AssertionError(); + } + iterationCount++; + } + return iterationCount; + } + + private static class TestNode extends Node { + + @Child TestNode child0; + @Child TestNode child1; + + private int visited; + + public TestNode() { + } + + } + + private static class TestRootNode extends RootNode { + + @Child TestNode child0; + + private int visited; + + public TestRootNode() { + super(TestingLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + return null; + } + + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/nodes/SafeReplaceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/nodes/SafeReplaceTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, 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.nodes; + +import com.oracle.truffle.api.TestingLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Tests optional method for ensuring that a node replacement is type safe. Ordinary node + * replacement is performed by unsafe assignment of a parent node's child field. + */ +public class SafeReplaceTest { + + @Test + public void testCorrectReplacement() { + TestRootNode root = new TestRootNode(); + final TestNode oldChild = new TestNode(); + final TestNode newChild = new TestNode(); + root.child = oldChild; + assertFalse(oldChild.isSafelyReplaceableBy(newChild)); // No parent node + root.adoptChildren(); + assertTrue(oldChild.isSafelyReplaceableBy(newChild)); // Now adopted by parent + // new node + oldChild.replace(newChild); + root.execute(null); + assertEquals(root.executed, 1); + assertEquals(oldChild.executed, 0); + assertEquals(newChild.executed, 1); + } + + @Test + public void testIncorrectReplacement() { + TestRootNode root = new TestRootNode(); + final TestNode oldChild = new TestNode(); + root.child = oldChild; + root.adoptChildren(); + final TestNode newChild = new TestNode(); + final TestNode strayChild = new TestNode(); + assertFalse(strayChild.isSafelyReplaceableBy(newChild)); // Stray not a child of parent + final WrongTestNode wrongTypeNewChild = new WrongTestNode(); + assertFalse(oldChild.isSafelyReplaceableBy(wrongTypeNewChild)); + } + + private static class TestNode extends Node { + + private int executed; + + public Object execute() { + executed++; + return null; + } + } + + private static class TestRootNode extends RootNode { + + @Child TestNode child; + + private int executed; + + public TestRootNode() { + super(TestingLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + executed++; + child.execute(); + return null; + } + } + + private static class WrongTestNode extends Node { + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/package.html Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,68 @@ + + + +

+ This package contains basic tests of the Truffle API and serves at the same time as an + introduction to the Truffle API for language implementors. Every test gives an example on how to + use the construct explained in the class description. +

+ +

+ Truffle is a language implementation framework. A guest language method is represented as a tree + of executable nodes. The framework provides mechanisms for those trees to call each other. + Additionally it contains dedicated data structures for storing data local to a tree invocation. +

+ +

+ This introduction to Truffle contains items in the following recommended order: + +

    +
  • How to get access to the Truffle runtime? + {@link com.oracle.truffle.api.test.TruffleRuntimeTest}
  • +
  • How to create a root node? {@link com.oracle.truffle.api.test.RootNodeTest}
  • +
  • How to create a child node and link it with its parent? + {@link com.oracle.truffle.api.test.ChildNodeTest}
  • +
  • How to create an array of child nodes? {@link com.oracle.truffle.api.test.ChildrenNodesTest} +
  • +
  • Why are final fields in node classes important? + {@link com.oracle.truffle.api.test.FinalFieldTest}
  • +
  • How to replace one node with another node and what for? + {@link com.oracle.truffle.api.test.ReplaceTest}
  • +
  • How to let one Truffle tree invoke another one? {@link com.oracle.truffle.api.test.CallTest} +
  • +
  • How to pass arguments when executing a tree? + {@link com.oracle.truffle.api.test.ArgumentsTest}
  • +
  • How to use frames and frame slots to store values local to an activation? + {@link com.oracle.truffle.api.test.FrameTest}
  • +
  • How to use type specialization and speculation for frame slots? + {@link com.oracle.truffle.api.test.FrameSlotTypeSpecializationTest}
  • +
  • How to use type specialization and speculation for node return values? + {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}
  • +
  • How to "instrument" an AST with nodes that can provide access to runtime state from external + tools {@code com.oracle.truffle.api.test.instrument.InstrumentationTest}
  • +
+ diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/BytesSourceSectionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/BytesSourceSectionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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.source; + +import com.oracle.truffle.api.source.Source; +import java.nio.charset.StandardCharsets; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class BytesSourceSectionTest { + + @Test + public void testSectionsFromLineNumberASCII() { + final byte[] bytes = "foo\nbar\nbaz\n".getBytes(StandardCharsets.US_ASCII); + final Source source = Source.fromBytes(bytes, "description", StandardCharsets.US_ASCII); + assertEquals("foo", source.createSection("identifier", 1).getCode()); + assertEquals("bar", source.createSection("identifier", 2).getCode()); + assertEquals("baz", source.createSection("identifier", 3).getCode()); + } + + @Test + public void testSectionsFromOffsetsASCII() { + final byte[] bytes = "foo\nbar\nbaz\n".getBytes(StandardCharsets.US_ASCII); + final Source source = Source.fromBytes(bytes, "description", StandardCharsets.US_ASCII); + assertEquals("foo", source.createSection("identifier", 0, 3).getCode()); + assertEquals("bar", source.createSection("identifier", 4, 3).getCode()); + assertEquals("baz", source.createSection("identifier", 8, 3).getCode()); + } + + @Test + public void testOffset() { + final byte[] bytes = "xxxfoo\nbar\nbaz\nxxx".getBytes(StandardCharsets.US_ASCII); + final Source source = Source.fromBytes(bytes, 3, bytes.length - 6, "description", StandardCharsets.US_ASCII); + assertEquals("foo", source.createSection("identifier", 0, 3).getCode()); + assertEquals("bar", source.createSection("identifier", 4, 3).getCode()); + assertEquals("baz", source.createSection("identifier", 8, 3).getCode()); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/JavaRecognizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/JavaRecognizer.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 2015, 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.source; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.spi.FileTypeDetector; + +public final class JavaRecognizer extends FileTypeDetector { + @Override + public String probeContentType(Path path) throws IOException { + if (path.getFileName().toString().endsWith(".java")) { + return "text/x-java"; + } + return null; + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceSectionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceSectionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013, 2015, 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.source; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; + +public class SourceSectionTest { + + private final Source emptySource = Source.fromText("", null); + + private final Source emptyLineSource = Source.fromText("\n", null); + + private final Source shortSource = Source.fromText("01", null); + + private final Source longSource = Source.fromText("01234\n67\n9\n", "long"); + + public void emptySourceTest0() { + SourceSection section = emptySource.createSection("test", 0, 0); + assertNotNull(section); + assertEquals(section.getCode(), ""); + } + + @Test + public void emptyLineTest0() { + SourceSection section = emptyLineSource.createSection("test", 0, 0); + assertNotNull(section); + assertEquals(section.getCode(), ""); + assertEquals(section.getCharIndex(), 0); + assertEquals(section.getCharLength(), 0); + assertEquals(section.getStartLine(), 1); + assertEquals(section.getStartColumn(), 1); + } + + @Test + public void emptyLineTest1() { + SourceSection section = emptyLineSource.createSection("test", 0, 1); + assertNotNull(section); + assertEquals(section.getCode(), "\n"); + assertEquals(section.getCharIndex(), 0); + assertEquals(section.getCharLength(), 1); + assertEquals(section.getStartLine(), 1); + assertEquals(section.getStartColumn(), 1); + assertEquals(section.getEndLine(), 1); + assertEquals(section.getEndColumn(), 1); + } + + @Test + public void emptySectionTest2() { + SourceSection section = shortSource.createSection("test", 0, 0); + assertNotNull(section); + assertEquals(section.getCode(), ""); + } + + @Test + public void emptySectionTest3() { + SourceSection section = longSource.createSection("test", 0, 0); + assertNotNull(section); + assertEquals(section.getCode(), ""); + } + + @Test + public void testGetCode() { + assertEquals("01234", longSource.createSection("test", 0, 5).getCode()); + assertEquals("67", longSource.createSection("test", 6, 2).getCode()); + assertEquals("9", longSource.createSection("test", 9, 1).getCode()); + } + + @Test + public void testGetShortDescription() { + assertEquals("long:1", longSource.createSection("test", 0, 5).getShortDescription()); + assertEquals("long:2", longSource.createSection("test", 6, 2).getShortDescription()); + assertEquals("long:3", longSource.createSection("test", 9, 1).getShortDescription()); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange1() { + longSource.createSection("test", 9, 5); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange2() { + longSource.createSection("test", -1, 1); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange3() { + longSource.createSection("test", 1, -1); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange4() { + longSource.createSection("test", 3, 1, 9, 5); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange5() { + longSource.createSection("test", 1, 1, -1, 1); + } + + @Test(expected = IllegalArgumentException.class) + public void testOutOfRange6() { + longSource.createSection("test", 1, 1, 1, -1); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013, 2015, 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.source; + +import com.oracle.truffle.api.source.Source; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import org.junit.Test; + +public class SourceTest { + @Test + public void assignMimeTypeAndIdentity() { + Source s1 = Source.fromText("// a comment\n", "Empty comment"); + assertNull("No mime type assigned", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForApppendable() { + Source s1 = Source.fromAppendableText(""); + assertNull("No mime type assigned", s1.getMimeType()); + s1.appendCode("// Hello"); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForBytes() { + String text = "// Hello"; + Source s1 = Source.fromBytes(text.getBytes(StandardCharsets.UTF_8), "Hello", StandardCharsets.UTF_8); + assertNull("No mime type assigned", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForReader() throws IOException { + String text = "// Hello"; + Source s1 = Source.fromReader(new StringReader(text), "Hello"); + assertNull("No mime type assigned", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForFile() throws IOException { + File file = File.createTempFile("Hello", ".java"); + file.deleteOnExit(); + + String text; + try (FileWriter w = new FileWriter(file)) { + text = "// Hello"; + w.write(text); + } + + // JDK8 default fails on OS X: https://bugs.openjdk.java.net/browse/JDK-8129632 + Source s1 = Source.fromFileName(file.getPath()).withMimeType("text/x-java"); + assertEquals("Recognized as Java", "text/x-java", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForVirtualFile() throws IOException { + File file = File.createTempFile("Hello", ".java"); + file.deleteOnExit(); + + String text = "// Hello"; + + // JDK8 default fails on OS X: https://bugs.openjdk.java.net/browse/JDK-8129632 + Source s1 = Source.fromFileName(text, file.getPath()).withMimeType("text/x-java"); + assertEquals("Recognized as Java", "text/x-java", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } + + @Test + public void assignMimeTypeAndIdentityForURL() throws IOException { + File file = File.createTempFile("Hello", ".java"); + file.deleteOnExit(); + + String text; + try (FileWriter w = new FileWriter(file)) { + text = "// Hello"; + w.write(text); + } + + Source s1 = Source.fromURL(file.toURI().toURL(), "Hello.java"); + assertEquals("Threated as plain", "text/plain", s1.getMimeType()); + Source s2 = s1.withMimeType("text/x-c"); + assertEquals("They have the same content", s1.getCode(), s2.getCode()); + assertEquals("// Hello", s1.getCode()); + assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); + assertNotEquals("So they are different", s1, s2); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceTextTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/source/SourceTextTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013, 2015, 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.source; + +import com.oracle.truffle.api.source.Source; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class SourceTextTest { + + private final Source emptySource = Source.fromText("", null); + + private final Source emptyLineSource = Source.fromText("\n", null); + + private final Source shortSource = Source.fromText("01", null); + + private final Source longSource = Source.fromText("01234\n67\n9\n", null); + + @Test + public void emptyTextTest0() { + assertEquals(emptySource.getLineCount(), 0); + } + + // Temp disable of empty text tests + + // @Test(expected = IllegalArgumentException.class) + @Test() + public void emptyTextTest1() { + emptySource.getLineNumber(0); + } + + // @Test(expected = IllegalArgumentException.class) + @Test() + public void emptyTextTest2() { + emptySource.getColumnNumber(0); + } + + @Test(expected = IllegalArgumentException.class) + public void emptyTextTest3() { + emptySource.getLineNumber(-1); + } + + // @Test(expected = IllegalArgumentException.class) + @Test() + public void emptyTextTest4() { + emptySource.getLineStartOffset(0); + } + + // @Test(expected = IllegalArgumentException.class) + public void emptyTextTest5() { + emptySource.getLineStartOffset(1); + } + + // @Test(expected = IllegalArgumentException.class) + public void emptyTextTest6() { + emptySource.getLineLength(1); + } + + @Test + public void emptyLineTest0() { + assertEquals(emptyLineSource.getLineCount(), 1); + assertEquals(emptyLineSource.getLineNumber(0), 1); + assertEquals(emptyLineSource.getLineStartOffset(1), 0); + assertEquals(emptyLineSource.getColumnNumber(0), 1); + assertEquals(emptyLineSource.getLineLength(1), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void emptyLineTest1() { + emptyLineSource.getLineNumber(1); + } + + @Test(expected = IllegalArgumentException.class) + public void emptyLineTest2() { + emptyLineSource.getLineStartOffset(2); + } + + @Test(expected = IllegalArgumentException.class) + public void emptyLineTest3() { + emptyLineSource.getColumnNumber(1); + } + + @Test(expected = IllegalArgumentException.class) + public void emptyLineTest4() { + emptyLineSource.getLineLength(2); + } + + @Test + public void shortTextTest0() { + + assertEquals(shortSource.getLineCount(), 1); + + assertEquals(shortSource.getLineNumber(0), 1); + assertEquals(shortSource.getLineStartOffset(1), 0); + assertEquals(shortSource.getColumnNumber(0), 1); + + assertEquals(shortSource.getLineNumber(1), 1); + assertEquals(shortSource.getColumnNumber(1), 2); + + assertEquals(shortSource.getLineLength(1), 2); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest1() { + shortSource.getLineNumber(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest2() { + shortSource.getColumnNumber(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest3() { + shortSource.getLineNumber(2); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest4() { + shortSource.getColumnNumber(2); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest5() { + shortSource.getLineLength(2); + } + + @Test(expected = IllegalArgumentException.class) + public void shortTextTest6() { + shortSource.getLineLength(2); + } + + @Test + public void longTextTest0() { + + assertEquals(longSource.getLineCount(), 3); + + assertEquals(longSource.getLineNumber(0), 1); + assertEquals(longSource.getLineStartOffset(1), 0); + assertEquals(longSource.getColumnNumber(0), 1); + + assertEquals(longSource.getLineNumber(4), 1); + assertEquals(longSource.getColumnNumber(4), 5); + + assertEquals(longSource.getLineNumber(5), 1); // newline + assertEquals(longSource.getColumnNumber(5), 6); // newline + assertEquals(longSource.getLineLength(1), 5); + + assertEquals(longSource.getLineNumber(6), 2); + assertEquals(longSource.getLineStartOffset(2), 6); + assertEquals(longSource.getColumnNumber(6), 1); + + assertEquals(longSource.getLineNumber(7), 2); + assertEquals(longSource.getColumnNumber(7), 2); + + assertEquals(longSource.getLineNumber(8), 2); // newline + assertEquals(longSource.getLineNumber(8), 2); // newline + assertEquals(longSource.getLineLength(2), 2); + + assertEquals(longSource.getLineNumber(9), 3); + assertEquals(longSource.getLineStartOffset(3), 9); + assertEquals(longSource.getColumnNumber(9), 1); + + assertEquals(longSource.getLineNumber(10), 3); // newline + assertEquals(longSource.getColumnNumber(10), 2); // newline + assertEquals(longSource.getLineLength(3), 1); + + } + + @Test(expected = IllegalArgumentException.class) + public void longTextTest1() { + longSource.getLineNumber(11); + } + + @Test(expected = IllegalArgumentException.class) + public void longTextTest2() { + longSource.getColumnNumber(11); + } + + @Test(expected = IllegalArgumentException.class) + public void longTextTest3() { + longSource.getLineStartOffset(4); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -/** - *

Passing Arguments

- * - *

- * When invoking a call target with {@link CallTarget#call(Object[])}, arguments can be passed. A - * Truffle node can access the arguments passed into the Truffle method by using - * {@link VirtualFrame#getArguments}. - *

- * - *

- * The arguments class should only contain fields that are declared as final. This allows the - * Truffle runtime to improve optimizations around guest language method calls. Also, the arguments - * object array must never be stored into a field. It should be created immediately before invoking - * {@link CallTarget#call(Object[])} and no longer be accessed afterwards. - *

- * - *

- * The next part of the Truffle API introduction is at {@link com.oracle.truffle.api.test.FrameTest} - * . - *

- */ -public class ArgumentsTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestRootNode rootNode = new TestRootNode(new TestArgumentNode[]{new TestArgumentNode(0), new TestArgumentNode(1)}); - CallTarget target = runtime.createCallTarget(rootNode); - Object result = target.call(new Object[]{20, 22}); - Assert.assertEquals(42, result); - } - - private static class TestRootNode extends RootNode { - - @Children private final TestArgumentNode[] children; - - TestRootNode(TestArgumentNode[] children) { - super(TestingLanguage.class, null, null); - this.children = children; - } - - @Override - public Object execute(VirtualFrame frame) { - int sum = 0; - for (int i = 0; i < children.length; ++i) { - sum += children[i].execute(frame); - } - return sum; - } - } - - private static class TestArgumentNode extends Node { - - private final int index; - - TestArgumentNode(int index) { - super(null); - this.index = index; - } - - int execute(VirtualFrame frame) { - return (Integer) frame.getArguments()[index]; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -/** - *

Calling Another Tree

- * - *

- * A guest language implementation can create multiple call targets using the - * {@link TruffleRuntime#createCallTarget(RootNode)} method. Those call targets can be passed around - * as normal Java objects and used for calling guest language methods. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.ArgumentsTest}. - *

- */ -public class CallTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - CallTarget foo = runtime.createCallTarget(new ConstantRootNode(20)); - CallTarget bar = runtime.createCallTarget(new ConstantRootNode(22)); - CallTarget main = runtime.createCallTarget(new DualCallNode(foo, bar)); - Object result = main.call(); - Assert.assertEquals(42, result); - } - - class DualCallNode extends RootNode { - - private final CallTarget firstTarget; - private final CallTarget secondTarget; - - DualCallNode(CallTarget firstTarget, CallTarget secondTarget) { - super(TestingLanguage.class, null, null); - this.firstTarget = firstTarget; - this.secondTarget = secondTarget; - } - - @Override - public Object execute(VirtualFrame frame) { - return ((Integer) firstTarget.call()) + ((Integer) secondTarget.call()); - } - } - - class ConstantRootNode extends RootNode { - - private final int value; - - public ConstantRootNode(int value) { - super(TestingLanguage.class, null, null); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return value; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import java.util.Iterator; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Creating a Child Node

- * - *

- * Child nodes are stored in the class of the parent node in fields that are marked with the - * {@link Child} annotation. The {@link Node#getParent()} method allows access to this field. Every - * node also provides the ability to iterate over its children using {@link Node#getChildren()}. - *

- * - *

- * A child node field must be declared private and non-final. It may only be assigned in the - * constructor of the parent node. For changing the structure of the tree at run time, the method - * {@link Node#replace(Node)} must be used (see {@link ReplaceTest}). - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.ChildrenNodesTest}. - *

- */ -public class ChildNodeTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestChildNode leftChild = new TestChildNode(); - TestChildNode rightChild = new TestChildNode(); - TestRootNode rootNode = new TestRootNode(leftChild, rightChild); - CallTarget target = runtime.createCallTarget(rootNode); - Assert.assertEquals(rootNode, leftChild.getParent()); - Assert.assertEquals(rootNode, rightChild.getParent()); - Iterator iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(leftChild, iterator.next()); - Assert.assertEquals(rightChild, iterator.next()); - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - Assert.assertEquals(42, result); - } - - class TestRootNode extends RootNode { - - @Child private TestChildNode left; - @Child private TestChildNode right; - - public TestRootNode(TestChildNode left, TestChildNode right) { - super(TestingLanguage.class, null, null); - this.left = left; - this.right = right; - } - - @Override - public Object execute(VirtualFrame frame) { - return left.execute() + right.execute(); - } - } - - class TestChildNode extends Node { - - public TestChildNode() { - super(null); - } - - public int execute() { - return 21; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import java.util.Iterator; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Creating an Array of Children Nodes

- * - *

- * An array of children nodes can be used as a field in a parent node. The field has to be annotated - * with {@link com.oracle.truffle.api.nodes.Node.Children} and must be declared private and final. - * Before assigning the field in the parent node constructor, {@link Node#adoptChildren} must be - * called in order to update the parent pointers in the child nodes. After filling the array with - * its first values, it must never be changed. It is only possible to call {@link Node#replace} on a - * child node. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.FinalFieldTest}. - *

- */ -public class ChildrenNodesTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestChildNode firstChild = new TestChildNode(); - TestChildNode secondChild = new TestChildNode(); - TestRootNode rootNode = new TestRootNode(new TestChildNode[]{firstChild, secondChild}); - CallTarget target = runtime.createCallTarget(rootNode); - Assert.assertEquals(rootNode, firstChild.getParent()); - Assert.assertEquals(rootNode, secondChild.getParent()); - Iterator iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(firstChild, iterator.next()); - Assert.assertEquals(secondChild, iterator.next()); - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - Assert.assertEquals(42, result); - } - - class TestRootNode extends RootNode { - - @Children private final TestChildNode[] children; - - public TestRootNode(TestChildNode[] children) { - super(TestingLanguage.class, null, null); - this.children = children; - } - - @Override - public Object execute(VirtualFrame frame) { - int sum = 0; - for (int i = 0; i < children.length; ++i) { - sum += children[i].execute(); - } - return sum; - } - } - - class TestChildNode extends Node { - - public TestChildNode() { - super(null); - } - - public int execute() { - return 21; - } - } - - @Test - public void testMultipleChildrenFields() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestChildNode firstChild = new TestChildNode(); - TestChildNode secondChild = new TestChildNode(); - TestChildNode thirdChild = new TestChildNode(); - TestChildNode forthChild = new TestChildNode(); - TestRootNode rootNode = new TestRoot2Node(new TestChildNode[]{firstChild, secondChild}, new TestChildNode[]{thirdChild, forthChild}); - CallTarget target = runtime.createCallTarget(rootNode); - Assert.assertEquals(rootNode, firstChild.getParent()); - Assert.assertEquals(rootNode, secondChild.getParent()); - Assert.assertEquals(rootNode, thirdChild.getParent()); - Assert.assertEquals(rootNode, forthChild.getParent()); - Iterator iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(firstChild, iterator.next()); - Assert.assertEquals(secondChild, iterator.next()); - Assert.assertEquals(thirdChild, iterator.next()); - Assert.assertEquals(forthChild, iterator.next()); - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - Assert.assertEquals(2 * 42, result); - } - - class TestRoot2Node extends TestRootNode { - @Children private final TestChildNode[] children1; - @Children private final TestChildNode[] children2; - - public TestRoot2Node(TestChildNode[] children1, TestChildNode[] children2) { - super(new TestChildNode[0]); - this.children1 = children1; - this.children2 = children2; - } - - @Override - public Object execute(VirtualFrame frame) { - int sum = 0; - for (int i = 0; i < children1.length; ++i) { - sum += children1[i].execute(); - } - for (int i = 0; i < children2.length; ++i) { - sum += children2[i].execute(); - } - return sum; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Using Final Fields in Node Classes

- * - *

- * The usage of final fields in node classes is highly encouraged. It is beneficial for performance - * to declare every field that is not pointing to a child node as final. This gives the Truffle - * runtime an increased opportunity to optimize this node. - *

- * - *

- * If a node has a value which may change at run time, but will rarely do so, it is recommended to - * speculate on the field being final. This involves starting executing with a node where this field - * is final and only if this turns out to be no longer the case, the node is replaced with an - * alternative implementation of the operation (see {@link ReplaceTest}). - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.ReplaceTest}. - *

- */ -public class FinalFieldTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestRootNode rootNode = new TestRootNode(new TestChildNode[]{new TestChildNode(20), new TestChildNode(22)}); - CallTarget target = runtime.createCallTarget(rootNode); - Object result = target.call(); - Assert.assertEquals(42, result); - } - - private static class TestRootNode extends RootNode { - - @Children private final TestChildNode[] children; - - public TestRootNode(TestChildNode[] children) { - super(TestingLanguage.class, null, null); - this.children = children; - } - - @Override - public Object execute(VirtualFrame frame) { - int sum = 0; - for (int i = 0; i < children.length; ++i) { - sum += children[i].execute(); - } - return sum; - } - } - - private static class TestChildNode extends Node { - - private final int value; - - public TestChildNode(int value) { - super(null); - this.value = value; - } - - public int execute() { - return value; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.FrameDescriptor; -import com.oracle.truffle.api.frame.FrameSlot; -import com.oracle.truffle.api.frame.FrameSlotKind; -import com.oracle.truffle.api.frame.FrameSlotTypeException; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Specializing Frame Slot Types

- * - *

- * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run - * time to a more generic type if necessary. The new type of a frame slot can be set using the - * {@link FrameSlot#setKind(FrameSlotKind)} method. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}. - *

- */ -public class FrameSlotTypeSpecializationTest { - - @Before - public void setInstrumentationTestMode() { - InstrumentationTestMode.set(true); - } - - @After - public void unsetInstrumentationTestMode() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode); - Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); - Object result = target.call(); - Assert.assertEquals("42", result); - Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); - } - - class TestRootNode extends RootNode { - - @Child TestChildNode left; - @Child TestChildNode right; - - public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { - super(TestingLanguage.class, null, descriptor); - this.left = left; - this.right = right; - } - - @Override - public Object execute(VirtualFrame frame) { - left.execute(frame); - return right.execute(frame); - } - } - - abstract class TestChildNode extends Node { - - protected TestChildNode() { - super(null); - } - - abstract Object execute(VirtualFrame frame); - } - - abstract class FrameSlotNode extends TestChildNode { - - protected final FrameSlot slot; - - public FrameSlotNode(FrameSlot slot) { - this.slot = slot; - } - } - - class StringTestChildNode extends TestChildNode { - - @Override - Object execute(VirtualFrame frame) { - return "42"; - } - - } - - class IntAssignLocal extends FrameSlotNode { - - @Child private TestChildNode value; - - IntAssignLocal(FrameSlot slot, TestChildNode value) { - super(slot); - this.value = value; - } - - @Override - Object execute(VirtualFrame frame) { - Object o = value.execute(frame); - if (o instanceof Integer) { - frame.setInt(slot, (Integer) o); - } else { - slot.setKind(FrameSlotKind.Object); - frame.setObject(slot, o); - this.replace(new ObjectAssignLocal(slot, value)); - } - return null; - } - } - - class ObjectAssignLocal extends FrameSlotNode { - - @Child private TestChildNode value; - - ObjectAssignLocal(FrameSlot slot, TestChildNode value) { - super(slot); - this.value = value; - } - - @Override - Object execute(VirtualFrame frame) { - Object o = value.execute(frame); - slot.setKind(FrameSlotKind.Object); - frame.setObject(slot, o); - return null; - } - } - - class IntReadLocal extends FrameSlotNode { - - IntReadLocal(FrameSlot slot) { - super(slot); - } - - @Override - Object execute(VirtualFrame frame) { - try { - return frame.getInt(slot); - } catch (FrameSlotTypeException e) { - return this.replace(new ObjectReadLocal(slot)).execute(frame); - } - } - } - - class ObjectReadLocal extends FrameSlotNode { - - ObjectReadLocal(FrameSlot slot) { - super(slot); - } - - @Override - Object execute(VirtualFrame frame) { - try { - return frame.getObject(slot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(e); - } - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.FrameDescriptor; -import com.oracle.truffle.api.frame.FrameInstance; -import com.oracle.truffle.api.frame.FrameSlot; -import com.oracle.truffle.api.frame.FrameSlotKind; -import com.oracle.truffle.api.frame.FrameSlotTypeException; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -/** - *

Storing Values in Frame Slots

- * - *

- * The frame is the preferred data structure for passing values between nodes. It can in particular - * be used for storing the values of local variables of the guest language. The - * {@link FrameDescriptor} represents the current structure of the frame. The method - * {@link FrameDescriptor#addFrameSlot(Object, FrameSlotKind)} can be used to create predefined - * frame slots. The setter and getter methods in the {@link Frame} class can be used to access the - * current value of a particular frame slot. Values can be removed from a frame via the - * {@link FrameDescriptor#removeFrameSlot(Object)} method. - *

- * - *

- * There are five primitive types for slots available: {@link java.lang.Boolean}, - * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float}, and - * {@link java.lang.Double} . It is encouraged to use those types whenever possible. Dynamically - * typed languages can speculate on the type of a value fitting into a primitive (see - * {@link FrameSlotTypeSpecializationTest}). When a frame slot is of one of those particular - * primitive types, its value may only be accessed with the respectively typed getter method ( - * {@link Frame#getBoolean}, {@link Frame#getInt}, {@link Frame#getLong}, {@link Frame#getFloat}, or - * {@link Frame#getDouble}) or setter method ({@link Frame#setBoolean}, {@link Frame#setInt}, - * {@link Frame#setLong}, {@link Frame#setFloat}, or {@link Frame#setDouble}) in the {@link Frame} - * class. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.FrameSlotTypeSpecializationTest}. - *

- */ -public class FrameTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() throws SecurityException, IllegalArgumentException { - TruffleRuntime runtime = Truffle.getRuntime(); - FrameDescriptor frameDescriptor = new FrameDescriptor(); - String varName = "localVar"; - FrameSlot slot = frameDescriptor.addFrameSlot(varName, FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(frameDescriptor, new AssignLocal(slot), new ReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode); - Object result = target.call(); - Assert.assertEquals(42, result); - frameDescriptor.removeFrameSlot(varName); - boolean slotMissing = false; - try { - result = target.call(); - } catch (IllegalArgumentException iae) { - slotMissing = true; - } - Assert.assertTrue(slotMissing); - } - - class TestRootNode extends RootNode { - - @Child TestChildNode left; - @Child TestChildNode right; - - public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { - super(TestingLanguage.class, null, descriptor); - this.left = left; - this.right = right; - } - - @Override - public Object execute(VirtualFrame frame) { - return left.execute(frame) + right.execute(frame); - } - } - - abstract class TestChildNode extends Node { - - public TestChildNode() { - super(null); - } - - abstract int execute(VirtualFrame frame); - } - - abstract class FrameSlotNode extends TestChildNode { - - protected final FrameSlot slot; - - public FrameSlotNode(FrameSlot slot) { - this.slot = slot; - } - } - - class AssignLocal extends FrameSlotNode { - - AssignLocal(FrameSlot slot) { - super(slot); - } - - @Override - int execute(VirtualFrame frame) { - frame.setInt(slot, 42); - return 0; - } - } - - class ReadLocal extends FrameSlotNode { - - ReadLocal(FrameSlot slot) { - super(slot); - } - - @Override - int execute(VirtualFrame frame) { - try { - return frame.getInt(slot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(e); - } - } - } - - @Test - public void framesCanBeMaterialized() { - final TruffleRuntime runtime = Truffle.getRuntime(); - - class FrameRootNode extends RootNode { - - public FrameRootNode() { - super(TestingLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - FrameInstance frameInstance = runtime.getCurrentFrame(); - Frame readWrite = frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, true); - Frame materialized = frameInstance.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true); - - assertTrue("Really materialized: " + materialized, materialized instanceof MaterializedFrame); - assertEquals("It's my frame", frame, readWrite); - return this; - } - } - - FrameRootNode frn = new FrameRootNode(); - Object ret = Truffle.getRuntime().createCallTarget(frn).call(); - assertEquals("Returns itself", frn, ret); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeInterface; -import com.oracle.truffle.api.nodes.NodeUtil; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import java.util.Iterator; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - * Test child fields declared with interface types instead of {@link Node} subclasses. - */ -public class InterfaceChildFieldTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void testChild() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestChildInterface leftChild = new TestLeafNode(); - TestChildInterface rightChild = new TestLeafNode(); - TestChildNode parent = new TestChildNode(leftChild, rightChild); - TestRootNode rootNode = new TestRootNode(parent); - CallTarget target = runtime.createCallTarget(rootNode); - Iterator iterator = parent.getChildren().iterator(); - Assert.assertEquals(leftChild, iterator.next()); - Assert.assertEquals(rightChild, iterator.next()); - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - Assert.assertEquals(42, result); - - Assert.assertEquals(4, NodeUtil.countNodes(rootNode)); - Assert.assertEquals(4, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); - } - - @Test - public void testChildren() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestChildInterface[] children = new TestChildInterface[5]; - for (int i = 0; i < children.length; i++) { - children[i] = new TestLeafNode(); - } - TestChildrenNode parent = new TestChildrenNode(children); - TestRootNode rootNode = new TestRootNode(parent); - CallTarget target = runtime.createCallTarget(rootNode); - Iterator iterator = parent.getChildren().iterator(); - for (int i = 0; i < children.length; i++) { - Assert.assertEquals(children[i], iterator.next()); - } - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - Assert.assertEquals(105, result); - - Assert.assertEquals(2 + children.length, NodeUtil.countNodes(rootNode)); - Assert.assertEquals(2 + children.length, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); - } - - class TestRootNode extends RootNode { - - @Child private TestChildInterface child; - - public TestRootNode(TestChildInterface child) { - super(TestingLanguage.class, null, null); - this.child = child; - } - - @Override - public Object execute(VirtualFrame frame) { - return child.executeIntf(); - } - } - - interface TestChildInterface extends NodeInterface { - int executeIntf(); - } - - class TestLeafNode extends Node implements TestChildInterface { - public TestLeafNode() { - super(null); - } - - public int executeIntf() { - return this.replace(new TestLeaf2Node()).executeIntf(); - } - } - - class TestLeaf2Node extends Node implements TestChildInterface { - public TestLeaf2Node() { - super(null); - } - - public int executeIntf() { - return 21; - } - } - - class TestChildNode extends Node implements TestChildInterface { - - @Child private TestChildInterface left; - @Child private TestChildInterface right; - - public TestChildNode(TestChildInterface left, TestChildInterface right) { - super(null); - this.left = left; - this.right = right; - } - - @Override - public int executeIntf() { - return left.executeIntf() + right.executeIntf(); - } - } - - class TestChildrenNode extends Node implements TestChildInterface { - - @Children private final TestChildInterface[] children; - - public TestChildrenNode(TestChildInterface[] children) { - super(null); - this.children = children; - } - - @Override - public int executeIntf() { - int sum = 0; - for (int i = 0; i < children.length; ++i) { - sum += children[i].executeIntf(); - } - return sum; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import java.util.Iterator; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -/** - *

Replacing Nodes at Run Time

- * - *

- * The structure of the Truffle tree can be changed at run time by replacing nodes using the - * {@link Node#replace(Node)} method. This method will automatically change the child pointer in the - * parent of the node and replace it with a pointer to the new node. - *

- * - *

- * Replacing nodes is a costly operation, so it should not happen too often. The convention is that - * the implementation of the Truffle nodes should ensure that there are maximal a small (and - * constant) number of node replacements per Truffle node. - *

- * - *

- * The next part of the Truffle API introduction is at {@link com.oracle.truffle.api.test.CallTest}. - *

- */ -public class ReplaceTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - UnresolvedNode leftChild = new UnresolvedNode("20"); - UnresolvedNode rightChild = new UnresolvedNode("22"); - TestRootNode rootNode = new TestRootNode(new ValueNode[]{leftChild, rightChild}); - CallTarget target = runtime.createCallTarget(rootNode); - assertEquals(rootNode, leftChild.getParent()); - assertEquals(rootNode, rightChild.getParent()); - Iterator iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(leftChild, iterator.next()); - Assert.assertEquals(rightChild, iterator.next()); - Assert.assertFalse(iterator.hasNext()); - Object result = target.call(); - assertEquals(42, result); - assertEquals(42, target.call()); - iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(ResolvedNode.class, iterator.next().getClass()); - Assert.assertEquals(ResolvedNode.class, iterator.next().getClass()); - Assert.assertFalse(iterator.hasNext()); - iterator = rootNode.getChildren().iterator(); - Assert.assertEquals(rootNode, iterator.next().getParent()); - Assert.assertEquals(rootNode, iterator.next().getParent()); - Assert.assertFalse(iterator.hasNext()); - } - - class TestRootNode extends RootNode { - - @Children private final ValueNode[] children; - - public TestRootNode(ValueNode[] children) { - super(TestingLanguage.class, null, null); - this.children = children; - } - - @Override - public Object execute(VirtualFrame frame) { - int sum = 0; - for (int i = 0; i < children.length; ++i) { - sum += children[i].execute(); - } - return sum; - } - } - - abstract class ValueNode extends Node { - - public ValueNode() { - super(null); - } - - abstract int execute(); - } - - class UnresolvedNode extends ValueNode { - - private final String value; - - public UnresolvedNode(String value) { - this.value = value; - } - - @Override - int execute() { - int intValue = Integer.parseInt(value); - ResolvedNode newNode = this.replace(new ResolvedNode(intValue)); - return newNode.execute(); - } - } - - class ResolvedNode extends ValueNode { - - private final int value; - - ResolvedNode(int value) { - this.value = value; - } - - @Override - int execute() { - return value; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.FrameDescriptor; -import com.oracle.truffle.api.frame.FrameSlot; -import com.oracle.truffle.api.frame.FrameSlotKind; -import com.oracle.truffle.api.frame.FrameSlotTypeException; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.nodes.UnexpectedResultException; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Specializing Return Types

- * - *

- * In order to avoid boxing and/or type casts on the return value of a node, the return value the - * method for executing a node can have a specific type and need not be of type - * {@link java.lang.Object}. For dynamically typed languages, this return type is something that - * should be speculated on. When the speculation fails and the child node cannot return the - * appropriate type of value, it can use an {@link UnexpectedResultException} to still pass the - * result to the caller. In such a case, the caller must rewrite itself to a more general version in - * order to avoid future failures of this kind. - *

- */ -public class ReturnTypeSpecializationTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode); - Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); - Object result = target.call(); - Assert.assertEquals("42", result); - Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); - } - - class TestRootNode extends RootNode { - - @Child TestChildNode left; - @Child TestChildNode right; - - public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { - super(TestingLanguage.class, null, descriptor); - this.left = left; - this.right = right; - } - - @Override - public Object execute(VirtualFrame frame) { - left.execute(frame); - return right.execute(frame); - } - } - - abstract class TestChildNode extends Node { - - public TestChildNode() { - super(null); - } - - abstract Object execute(VirtualFrame frame); - - int executeInt(VirtualFrame frame) throws UnexpectedResultException { - Object result = execute(frame); - if (result instanceof Integer) { - return (Integer) result; - } - throw new UnexpectedResultException(result); - } - } - - abstract class FrameSlotNode extends TestChildNode { - - protected final FrameSlot slot; - - public FrameSlotNode(FrameSlot slot) { - this.slot = slot; - } - } - - class StringTestChildNode extends TestChildNode { - - @Override - Object execute(VirtualFrame frame) { - return "42"; - } - - } - - class IntAssignLocal extends FrameSlotNode { - - @Child private TestChildNode value; - - IntAssignLocal(FrameSlot slot, TestChildNode value) { - super(slot); - this.value = value; - } - - @Override - Object execute(VirtualFrame frame) { - try { - int result = value.executeInt(frame); - frame.setInt(slot, result); - } catch (UnexpectedResultException e) { - slot.setKind(FrameSlotKind.Object); - frame.setObject(slot, e.getResult()); - replace(new ObjectAssignLocal(slot, value)); - } - return null; - } - } - - class ObjectAssignLocal extends FrameSlotNode { - - @Child private TestChildNode value; - - ObjectAssignLocal(FrameSlot slot, TestChildNode value) { - super(slot); - this.value = value; - } - - @Override - Object execute(VirtualFrame frame) { - Object o = value.execute(frame); - slot.setKind(FrameSlotKind.Object); - frame.setObject(slot, o); - return null; - } - } - - class IntReadLocal extends FrameSlotNode { - - IntReadLocal(FrameSlot slot) { - super(slot); - } - - @Override - Object execute(VirtualFrame frame) { - try { - return frame.getInt(slot); - } catch (FrameSlotTypeException e) { - return replace(new ObjectReadLocal(slot)).execute(frame); - } - } - - @Override - int executeInt(VirtualFrame frame) throws UnexpectedResultException { - try { - return frame.getInt(slot); - } catch (FrameSlotTypeException e) { - return replace(new ObjectReadLocal(slot)).executeInt(frame); - } - } - } - - class ObjectReadLocal extends FrameSlotNode { - - ObjectReadLocal(FrameSlot slot) { - super(slot); - } - - @Override - Object execute(VirtualFrame frame) { - try { - return frame.getObject(slot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(e); - } - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -/** - *

Creating a Root Node

- * - *

- * A Truffle root node is the entry point into a Truffle tree that represents a guest language - * method. It contains a {@link RootNode#execute(VirtualFrame)} method that can return a - * {@link java.lang.Object} value as the result of the guest language method invocation. This method - * must however never be called directly. Instead, the Truffle runtime must be used to create a - * {@link CallTarget} object from a root node using the - * {@link TruffleRuntime#createCallTarget(RootNode)} method. This call target object can then be - * executed using the {@link CallTarget#call(Object...)} method or one of its overloads. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.ChildNodeTest}. - *

- */ -public class RootNodeTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - TestRootNode rootNode = new TestRootNode(); - CallTarget target = runtime.createCallTarget(rootNode); - Object result = target.call(); - Assert.assertEquals(42, result); - } - - class TestRootNode extends RootNode { - - public TestRootNode() { - super(TestingLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - return 42; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2015, 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.test; - -import java.io.IOException; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; - -public final class TestingLanguage extends TruffleLanguage { - public static final TestingLanguage INSTANCE = new TestingLanguage(); - - private TestingLanguage() { - } - - @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - throw new IOException(); - } - - @Override - protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal(Object context) { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected Visualizer getVisualizer() { - return null; - } - - @Override - protected boolean isInstrumentable(Node node) { - return false; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - return null; - } - - @Override - protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { - return null; - } - - @Override - protected Object createContext(Env env) { - return null; - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeUtil; -import com.oracle.truffle.api.nodes.RootNode; -import java.util.Random; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import org.junit.Ignore; -import org.junit.Test; - -/** - * Test node rewriting in a tree shared across multiple threads (run with -ea). - */ -public class ThreadSafetyTest { - - @Test - @Ignore("sporadic failures with \"expected:<1000000> but was:<999999>\"") - public void test() throws InterruptedException { - TruffleRuntime runtime = Truffle.getRuntime(); - TestRootNode rootNode1 = new TestRootNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new ConstNode(42))))))); - final CallTarget target1 = runtime.createCallTarget(rootNode1); - NodeUtil.verify(rootNode1); - - RecursiveCallNode callNode = new RecursiveCallNode(new ConstNode(42)); - TestRootNode rootNode2 = new TestRootNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(callNode)))))); - final CallTarget target2 = runtime.createCallTarget(rootNode2); - callNode.setCallNode(runtime.createDirectCallNode(target2)); - NodeUtil.verify(rootNode2); - - testTarget(target1, 47, 1_000_000); - testTarget(target2, 72, 1_000_000); - } - - private static void testTarget(final CallTarget target, final int expectedResult, final int numberOfIterations) throws InterruptedException { - ExecutorService executorService = Executors.newFixedThreadPool(20); - final AtomicInteger ai = new AtomicInteger(); - for (int i = 0; i < numberOfIterations; i++) { - executorService.submit(new Runnable() { - public void run() { - try { - Object result = target.call(new Object[]{5}); - assertEquals(expectedResult, result); - ai.incrementAndGet(); - } catch (Throwable t) { - t.printStackTrace(System.out); - } - } - }); - } - executorService.shutdown(); - executorService.awaitTermination(90, TimeUnit.SECONDS); - assertTrue("test did not terminate", executorService.isTerminated()); - assertEquals(numberOfIterations, ai.get()); - } - - static class TestRootNode extends RootNode { - - @Child private ValueNode child; - - public TestRootNode(ValueNode child) { - super(TestingLanguage.class, null, null); - this.child = child; - } - - @Override - public Object execute(VirtualFrame frame) { - return child.execute(frame); - } - } - - abstract static class ValueNode extends Node { - - public ValueNode() { - super(null); - } - - abstract int execute(VirtualFrame frame); - } - - static class RewritingNode extends ValueNode { - - @Child private ValueNode child; - private final Random random; - - public RewritingNode(ValueNode child) { - this(child, new Random()); - } - - public RewritingNode(ValueNode child, Random random) { - this.child = child; - this.random = random; - } - - @Override - int execute(VirtualFrame frame) { - boolean replace = random.nextBoolean(); - if (replace) { - ValueNode newNode = this.replace(new OtherRewritingNode(child, random)); - return newNode.execute(frame); - } - return 1 + child.execute(frame); - } - } - - static class OtherRewritingNode extends ValueNode { - - @Child private ValueNode child; - private final Random random; - - public OtherRewritingNode(ValueNode child, Random random) { - this.child = child; - this.random = random; - } - - @Override - int execute(VirtualFrame frame) { - boolean replace = random.nextBoolean(); - if (replace) { - ValueNode newNode = this.replace(new RewritingNode(child, random)); - return newNode.execute(frame); - } - return 1 + child.execute(frame); - } - } - - static class ConstNode extends ValueNode { - - private final int value; - - ConstNode(int value) { - this.value = value; - } - - @Override - int execute(VirtualFrame frame) { - return value; - } - } - - static class RecursiveCallNode extends ValueNode { - @Child DirectCallNode callNode; - @Child private ValueNode valueNode; - - RecursiveCallNode(ValueNode value) { - this.valueNode = value; - } - - @Override - int execute(VirtualFrame frame) { - int arg = (Integer) frame.getArguments()[0]; - if (arg > 0) { - return (int) callNode.call(frame, new Object[]{(arg - 1)}); - } else { - return valueNode.execute(frame); - } - } - - void setCallNode(DirectCallNode callNode) { - this.callNode = insert(callNode); - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * Copyright (c) 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.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.NodeUtil; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -/** - *

Accessing the Truffle Runtime

- * - *

- * The Truffle runtime can be accessed at any point in time globally using the static method - * {@link Truffle#getRuntime()}. This method is guaranteed to return a non-null Truffle runtime - * object with an identifying name. A Java Virtual Machine implementation can chose to replace the - * default implementation of the {@link TruffleRuntime} interface with its own implementation for - * providing improved performance. - *

- * - *

- * The next part of the Truffle API introduction is at - * {@link com.oracle.truffle.api.test.RootNodeTest}. - *

- */ -public class TruffleRuntimeTest { - - private TruffleRuntime runtime; - - @Before - public void before() { - InstrumentationTestMode.set(true); - this.runtime = Truffle.getRuntime(); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - private static RootNode createTestRootNode(SourceSection sourceSection) { - return new RootNode(TestingLanguage.class, sourceSection, null) { - @Override - public Object execute(VirtualFrame frame) { - return 42; - } - }; - } - - // @Test - public void verifyTheRealRuntimeIsUsedOnRealGraal() { - TruffleRuntime r = Truffle.getRuntime(); - final String name = r.getClass().getName(); - if (name.endsWith("DefaultTruffleRuntime")) { - fail("Wrong name " + name + " with following System.getProperties:\n" + System.getProperties().toString()); - } - } - - @Test - public void test() { - assertNotNull(runtime); - assertNotNull(runtime.getName()); - } - - @Test - public void testCreateCallTarget() { - RootNode rootNode = createTestRootNode(null); - RootCallTarget target = runtime.createCallTarget(rootNode); - assertNotNull(target); - assertEquals(target.call(), 42); - assertSame(rootNode, target.getRootNode()); - } - - @Test - public void testGetCallTargets1() { - RootNode rootNode = createTestRootNode(null); - RootCallTarget target = runtime.createCallTarget(rootNode); - assertTrue(runtime.getCallTargets().contains(target)); - } - - @Test - public void testGetCallTargets2() { - RootNode rootNode = createTestRootNode(null); - RootCallTarget target1 = runtime.createCallTarget(rootNode); - RootCallTarget target2 = runtime.createCallTarget(rootNode); - assertTrue(runtime.getCallTargets().contains(target1)); - assertTrue(runtime.getCallTargets().contains(target2)); - } - - /* - * This test case documents the use case for profilers and debuggers where they need to access - * multiple call targets for the same source section. This case may happen when the optimization - * system decides to duplicate call targets to achieve better performance. - */ - @Test - public void testGetCallTargets3() { - Source source1 = Source.fromText("a\nb\n", ""); - SourceSection sourceSection1 = source1.createSection("foo", 1); - SourceSection sourceSection2 = source1.createSection("bar", 2); - - RootNode rootNode1 = createTestRootNode(sourceSection1); - RootNode rootNode2 = createTestRootNode(sourceSection2); - RootNode rootNode2Copy = NodeUtil.cloneNode(rootNode2); - - assertSame(rootNode2.getSourceSection(), rootNode2Copy.getSourceSection()); - - RootCallTarget target1 = runtime.createCallTarget(rootNode1); - RootCallTarget target2 = runtime.createCallTarget(rootNode2); - RootCallTarget target2Copy = runtime.createCallTarget(rootNode2Copy); - - Map> groupedTargets = groupUniqueCallTargets(); - - List targets1 = groupedTargets.get(sourceSection1); - assertEquals(1, targets1.size()); - assertEquals(target1, targets1.get(0)); - - List targets2 = groupedTargets.get(sourceSection2); - assertEquals(2, targets2.size()); - // order of targets2 is not guaranteed - assertTrue(target2 == targets2.get(0) ^ target2Copy == targets2.get(0)); - assertTrue(target2 == targets2.get(1) ^ target2Copy == targets2.get(1)); - } - - private static Map> groupUniqueCallTargets() { - Map> groupedTargets = new HashMap<>(); - for (RootCallTarget target : Truffle.getRuntime().getCallTargets()) { - SourceSection section = target.getRootNode().getSourceSection(); - if (section == null) { - // can not identify root node to a unique call target. Print warning? - continue; - } - List targets = groupedTargets.get(section); - if (targets == null) { - targets = new ArrayList<>(); - groupedTargets.put(section, targets); - } - targets.add(target); - } - return groupedTargets; - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/EvalInstrumentTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/EvalInstrumentTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2015, 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.test.instrument; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.lang.reflect.Field; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.EvalInstrumentListener; -import com.oracle.truffle.api.instrument.Instrument; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.SyntaxTag; -import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.instrument.InstrumentationTestingLanguage.InstrumentTestTag; -import com.oracle.truffle.api.vm.PolyglotEngine; - -/** - * Tests the kind of instrumentation where a client can provide guest language code to be - * spliced directly into the AST. - */ -public class EvalInstrumentTest { - - PolyglotEngine vm; - Instrumenter instrumenter; - - @Before - public void before() { - // TODO (mlvdv) eventually abstract this - try { - vm = PolyglotEngine.newBuilder().build(); - final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - instrumenter = (Instrumenter) field.get(vm); - final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); - testVMField.setAccessible(true); - testVMField.set(instrumenter, vm); - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { - fail("Reflective access to Instrumenter for testing"); - } - } - - @After - public void after() { - vm.dispose(); - vm = null; - instrumenter = null; - } - - @Test - public void testEvalInstrumentListener() throws IOException { - - instrumenter.registerASTProber(new InstrumentationTestingLanguage.TestASTProber()); - final Source source13 = InstrumentationTestingLanguage.createAdditionSource13("testEvalInstrumentListener"); - - final Probe[] addNodeProbe = new Probe[1]; - instrumenter.addProbeListener(new DefaultProbeListener() { - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - if (tag == InstrumentTestTag.ADD_TAG) { - addNodeProbe[0] = probe; - } - } - }); - assertEquals(vm.eval(source13).get(), 13); - assertNotNull("Add node should be probed", addNodeProbe[0]); - - final Source source42 = InstrumentationTestingLanguage.createConstantSource42("testEvalInstrumentListener"); - final int[] evalResult = {0}; - final int[] evalCount = {0}; - final Instrument instrument = instrumenter.attach(addNodeProbe[0], source42, new EvalInstrumentListener() { - - public void onExecution(Node node, VirtualFrame vFrame, Object result) { - evalCount[0] = evalCount[0] + 1; - if (result instanceof Integer) { - evalResult[0] = (Integer) result; - } - } - - public void onFailure(Node node, VirtualFrame vFrame, Exception ex) { - fail("Eval test evaluates without exception"); - - } - }, "test EvalInstrument", null); - - assertEquals(vm.eval(source13).get(), 13); - assertEquals(evalCount[0], 1); - assertEquals(evalResult[0], 42); - - // Second execution; same result - assertEquals(vm.eval(source13).get(), 13); - assertEquals(evalCount[0], 2); - assertEquals(evalResult[0], 42); - - // Add new eval instrument with no listener, no effect on third execution - instrumenter.attach(addNodeProbe[0], source42, null, "", null); - assertEquals(vm.eval(source13).get(), 13); - assertEquals(evalCount[0], 3); - assertEquals(evalResult[0], 42); - - // Remove original instrument; no further effect from fourth execution - instrument.dispose(); - evalResult[0] = 0; - assertEquals(vm.eval(source13).get(), 13); - assertEquals(evalCount[0], 3); - assertEquals(evalResult[0], 0); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,385 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.instrument; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.lang.reflect.Field; - -import org.junit.Test; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.ProbeInstrument; -import com.oracle.truffle.api.instrument.SimpleInstrumentListener; -import com.oracle.truffle.api.instrument.StandardInstrumentListener; -import com.oracle.truffle.api.instrument.SyntaxTag; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; -import com.oracle.truffle.api.instrument.impl.DefaultSimpleInstrumentListener; -import com.oracle.truffle.api.instrument.impl.DefaultStandardInstrumentListener; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeVisitor; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestAdditionNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestLanguageNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestValueNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestingLanguage.InstrumentTestTag; -import com.oracle.truffle.api.vm.PolyglotEngine; - -/** - *

AST Instrumentation

- * - * Instrumentation allows the insertion into Truffle ASTs language-specific instances of - * {@link WrapperNode} that propagate execution events through a {@link Probe} to any instances of - * {@link ProbeInstrument} that might be attached to the particular probe by tools. - */ -public class InstrumentationTest { - - @Test - public void testProbing() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { - final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); - final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - final Instrumenter instrumenter = (Instrumenter) field.get(vm); - instrumenter.registerASTProber(new TestASTProber(instrumenter)); - final Source source = InstrumentationTestingLanguage.createAdditionSource13("testProbing"); - - final Probe[] probes = new Probe[3]; - instrumenter.addProbeListener(new DefaultProbeListener() { - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - if (tag == InstrumentTestTag.ADD_TAG) { - assertEquals(probes[0], null); - probes[0] = probe; - } else if (tag == InstrumentTestTag.VALUE_TAG) { - if (probes[1] == null) { - probes[1] = probe; - } else if (probes[2] == null) { - probes[2] = probe; - } else { - fail("Should only be three probes"); - } - } - } - }); - assertEquals(vm.eval(source).get(), 13); - assertNotNull("Add node should be probed", probes[0]); - assertNotNull("Value nodes should be probed", probes[1]); - assertNotNull("Value nodes should be probed", probes[2]); - // Check instrumentation with the simplest kind of counters. - // They should all be removed when the check is finished. - checkCounters(probes[0], vm, source, new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter)); - - // Now try with the more complex flavor of listener - checkCounters(probes[0], vm, source, new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter)); - - } - - @Test - public void testTagging() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { - - final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); - final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - final Instrumenter instrumenter = (Instrumenter) field.get(vm); - final Source source = InstrumentationTestingLanguage.createAdditionSource13("testTagging"); - - // Applies appropriate tags - final TestASTProber astProber = new TestASTProber(instrumenter); - instrumenter.registerASTProber(astProber); - - // Listens for probes and tags being added - final TestProbeListener probeListener = new TestProbeListener(); - instrumenter.addProbeListener(probeListener); - - assertEquals(13, vm.eval(source).get()); - - // Check that the prober added probes to the tree - assertEquals(probeListener.probeCount, 3); - assertEquals(probeListener.tagCount, 3); - - assertEquals(instrumenter.findProbesTaggedAs(InstrumentTestTag.ADD_TAG).size(), 1); - assertEquals(instrumenter.findProbesTaggedAs(InstrumentTestTag.VALUE_TAG).size(), 2); - } - - private static void checkCounters(Probe probe, PolyglotEngine vm, Source source, TestCounter counterA, TestCounter counterB, TestCounter counterC) throws IOException { - - // Attach a counting instrument to the probe - counterA.attach(probe); - - // Attach a second counting instrument to the probe - counterB.attach(probe); - - // Run it again and check that the two instruments are working - assertEquals(13, vm.eval(source).get()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 1); - assertEquals(counterB.leaveCount(), 1); - - // Remove counterA - counterA.dispose(); - - // Run it again and check that instrument B is still working but not A - assertEquals(13, vm.eval(source).get()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 2); - assertEquals(counterB.leaveCount(), 2); - - // Attach a second instrument to the probe - counterC.attach(probe); - - // Run the original and check that instruments B,C working but not A - assertEquals(13, vm.eval(source).get()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 3); - assertEquals(counterB.leaveCount(), 3); - assertEquals(counterC.enterCount(), 1); - assertEquals(counterC.leaveCount(), 1); - - // Remove instrumentC - counterC.dispose(); - - // Run the original and check that instrument B working but not A,C - assertEquals(13, vm.eval(source).get()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 4); - assertEquals(counterB.leaveCount(), 4); - assertEquals(counterC.enterCount(), 1); - assertEquals(counterC.leaveCount(), 1); - - // Remove instrumentB - counterB.dispose(); - - // Check that no instruments working - assertEquals(13, vm.eval(source).get()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 4); - assertEquals(counterB.leaveCount(), 4); - assertEquals(counterC.enterCount(), 1); - assertEquals(counterC.leaveCount(), 1); - } - - private interface TestCounter { - - int enterCount(); - - int leaveCount(); - - void attach(Probe probe); - - void dispose(); - } - - /** - * A counter for the number of times execution enters and leaves a probed AST node. - */ - private class TestSimpleInstrumentCounter implements TestCounter { - - public int enterCount = 0; - public int leaveCount = 0; - public Instrumenter instrumenter; - private ProbeInstrument instrument; - - public TestSimpleInstrumentCounter(Instrumenter instrumenter) { - this.instrumenter = instrumenter; - } - - @Override - public int enterCount() { - return enterCount; - } - - @Override - public int leaveCount() { - return leaveCount; - } - - @Override - public void attach(Probe probe) { - instrument = instrumenter.attach(probe, new SimpleInstrumentListener() { - - public void onEnter(Probe p) { - enterCount++; - } - - public void onReturnVoid(Probe p) { - leaveCount++; - } - - public void onReturnValue(Probe p, Object result) { - leaveCount++; - } - - public void onReturnExceptional(Probe p, Throwable exception) { - leaveCount++; - } - }, "Instrumentation Test Counter"); - } - - @Override - public void dispose() { - instrument.dispose(); - } - } - - /** - * A counter for the number of times execution enters and leaves a probed AST node. - */ - private class TestStandardInstrumentCounter implements TestCounter { - - public int enterCount = 0; - public int leaveCount = 0; - public final Instrumenter instrumenter; - public ProbeInstrument instrument; - - public TestStandardInstrumentCounter(Instrumenter instrumenter) { - this.instrumenter = instrumenter; - } - - @Override - public int enterCount() { - return enterCount; - } - - @Override - public int leaveCount() { - return leaveCount; - } - - @Override - public void attach(Probe probe) { - instrument = instrumenter.attach(probe, new StandardInstrumentListener() { - - public void onEnter(Probe p, Node node, VirtualFrame vFrame) { - enterCount++; - } - - public void onReturnVoid(Probe p, Node node, VirtualFrame vFrame) { - leaveCount++; - } - - public void onReturnValue(Probe p, Node node, VirtualFrame vFrame, Object result) { - leaveCount++; - } - - public void onReturnExceptional(Probe p, Node node, VirtualFrame vFrame, Throwable exception) { - leaveCount++; - } - }, "Instrumentation Test Counter"); - } - - @Override - public void dispose() { - instrument.dispose(); - } - } - - /** - * Tags selected nodes on newly constructed ASTs. - */ - private static final class TestASTProber implements NodeVisitor, ASTProber { - - private final Instrumenter instrumenter; - - TestASTProber(Instrumenter instrumenter) { - this.instrumenter = instrumenter; - } - - @Override - public boolean visit(Node node) { - if (node instanceof TestLanguageNode) { - - final TestLanguageNode testNode = (TestLanguageNode) node; - - if (node instanceof TestValueNode) { - instrumenter.probe(testNode).tagAs(InstrumentTestTag.VALUE_TAG, null); - - } else if (node instanceof TestAdditionNode) { - instrumenter.probe(testNode).tagAs(InstrumentTestTag.ADD_TAG, null); - - } - } - return true; - } - - @Override - public void probeAST(Instrumenter inst, RootNode rootNode) { - rootNode.accept(this); - } - } - - /** - * Counts the number of "enter" events at probed nodes using the simplest AST listener. - */ - static final class TestSimpleInstrumentListener extends DefaultSimpleInstrumentListener { - - public int counter = 0; - - @Override - public void onEnter(Probe probe) { - counter++; - } - } - - /** - * Counts the number of "enter" events at probed nodes using the AST listener. - */ - static final class TestASTInstrumentListener extends DefaultStandardInstrumentListener { - - public int counter = 0; - - @Override - public void onEnter(Probe probe, Node node, VirtualFrame vFrame) { - counter++; - } - } - - private static final class TestProbeListener extends DefaultProbeListener { - - public int probeCount = 0; - public int tagCount = 0; - - @Override - public void newProbeInserted(Probe probe) { - probeCount++; - } - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - tagCount++; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.instrument; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.EventHandlerNode; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.nodes.RootNode; - -/** - * Tests instrumentation where a client can attach a node that gets attached into the AST. - */ -class InstrumentationTestNodes { - - abstract static class TestLanguageNode extends Node { - public abstract Object execute(VirtualFrame vFrame); - - } - - @NodeInfo(cost = NodeCost.NONE) - static class TestLanguageWrapperNode extends TestLanguageNode implements WrapperNode { - @Child private TestLanguageNode child; - @Child private EventHandlerNode eventHandlerNode; - - public TestLanguageWrapperNode(TestLanguageNode child) { - assert !(child instanceof TestLanguageWrapperNode); - this.child = child; - } - - @Override - public String instrumentationInfo() { - return "Wrapper node for testing"; - } - - @Override - public void insertEventHandlerNode(EventHandlerNode eventHandler) { - this.eventHandlerNode = eventHandler; - } - - @Override - public Probe getProbe() { - return eventHandlerNode.getProbe(); - } - - @Override - public Node getChild() { - return child; - } - - @Override - public Object execute(VirtualFrame vFrame) { - eventHandlerNode.enter(child, vFrame); - Object result; - try { - result = child.execute(vFrame); - eventHandlerNode.returnValue(child, vFrame, result); - } catch (Exception e) { - eventHandlerNode.returnExceptional(child, vFrame, e); - throw (e); - } - return result; - } - } - - /** - * A simple node for our test language to store a value. - */ - static class TestValueNode extends TestLanguageNode { - private final int value; - - public TestValueNode(int value) { - this.value = value; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return new Integer(this.value); - } - } - - /** - * A node for our test language that adds up two {@link TestValueNode}s. - */ - static class TestAdditionNode extends TestLanguageNode { - @Child private TestLanguageNode leftChild; - @Child private TestLanguageNode rightChild; - - public TestAdditionNode(TestValueNode leftChild, TestValueNode rightChild) { - this.leftChild = insert(leftChild); - this.rightChild = insert(rightChild); - } - - @Override - public Object execute(VirtualFrame vFrame) { - return new Integer(((Integer) leftChild.execute(vFrame)).intValue() + ((Integer) rightChild.execute(vFrame)).intValue()); - } - } - - /** - * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST - * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle - * completes an AST. The root nodes serves as our entry point into a program. - */ - static class InstrumentationTestRootNode extends RootNode { - @Child private TestLanguageNode body; - - /** - * This constructor emulates the global machinery that applies registered probers to every - * newly created AST. Global registry is not used, since that would interfere with other - * tests run in the same environment. - */ - public InstrumentationTestRootNode(TestLanguageNode body) { - super(InstrumentationTestingLanguage.class, null, null); - this.body = body; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return body.execute(vFrame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - } - - /** - * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST - * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle - * completes an AST. The root nodes serves as our entry point into a program. - */ - static class TestRootNode extends RootNode { - @Child private TestLanguageNode body; - - final Instrumenter instrumenter; - - /** - * This constructor emulates the global machinery that applies registered probers to every - * newly created AST. Global registry is not used, since that would interfere with other - * tests run in the same environment. - */ - public TestRootNode(TestLanguageNode body, Instrumenter instrumenter) { - super(InstrumentationTestingLanguage.class, null, null); - this.instrumenter = instrumenter; - this.body = body; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return body.execute(vFrame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestingLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestingLanguage.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.instrument; - -import java.io.IOException; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.SyntaxTag; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeVisitor; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.InstrumentationTestRootNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestAdditionNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestLanguageNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestLanguageWrapperNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestValueNode; - -@TruffleLanguage.Registration(name = "instrumentationTestLanguage", version = "0", mimeType = "text/x-instTest") -public final class InstrumentationTestingLanguage extends TruffleLanguage { - - public static final InstrumentationTestingLanguage INSTANCE = new InstrumentationTestingLanguage(); - - private static final String ADD_SOURCE_TEXT = "Fake source text for testing: parses to 6 + 7"; - private static final String CONSTANT_SOURCE_TEXT = "Fake source text for testing: parses to 42"; - - /** Use a unique test name to avoid unexpected CallTarget sharing. */ - static Source createAdditionSource13(String testName) { - return Source.fromText(ADD_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); - } - - /** Use a unique test name to avoid unexpected CallTarget sharing. */ - static Source createConstantSource42(String testName) { - return Source.fromText(CONSTANT_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); - } - - static enum InstrumentTestTag implements SyntaxTag { - - ADD_TAG("addition", "test language addition node"), - - VALUE_TAG("value", "test language value node"); - - private final String name; - private final String description; - - private InstrumentTestTag(String name, String description) { - this.name = name; - this.description = description; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - } - - private InstrumentationTestingLanguage() { - } - - @Override - protected CallTarget parse(Source source, Node context, String... argumentNames) throws IOException { - if (source.getCode().equals(ADD_SOURCE_TEXT)) { - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); - final TruffleRuntime runtime = Truffle.getRuntime(); - final CallTarget callTarget = runtime.createCallTarget(rootNode); - return callTarget; - } - if (source.getCode().equals(CONSTANT_SOURCE_TEXT)) { - final TestValueNode constantNode = new TestValueNode(42); - final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(constantNode); - final TruffleRuntime runtime = Truffle.getRuntime(); - final CallTarget callTarget = runtime.createCallTarget(rootNode); - return callTarget; - } - return null; - } - - @Override - protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal(Object context) { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected Visualizer getVisualizer() { - return null; - } - - @Override - protected boolean isInstrumentable(Node node) { - return node instanceof TestAdditionNode || node instanceof TestValueNode; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - if (isInstrumentable(node)) { - return new TestLanguageWrapperNode((TestLanguageNode) node); - } - return null; - } - - @Override - protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { - return null; - } - - @Override - protected Object createContext(Env env) { - return null; - } - - static final class TestASTProber implements ASTProber { - - public void probeAST(final Instrumenter instrumenter, RootNode startNode) { - startNode.accept(new NodeVisitor() { - - @Override - public boolean visit(Node node) { - if (node instanceof TestLanguageNode) { - - final TestLanguageNode testNode = (TestLanguageNode) node; - - if (node instanceof TestValueNode) { - instrumenter.probe(testNode).tagAs(InstrumentTestTag.VALUE_TAG, null); - - } else if (node instanceof TestAdditionNode) { - instrumenter.probe(testNode).tagAs(InstrumentTestTag.ADD_TAG, null); - - } - } - return true; - } - }); - } - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/ForeignAccessSingleThreadedTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/ForeignAccessSingleThreadedTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.interop; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.Node; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Test; - -public class ForeignAccessSingleThreadedTest implements ForeignAccess.Factory, TruffleObject { - ForeignAccess fa; - private int cnt; - - @Before - public void initInDifferentThread() throws InterruptedException { - Thread t = new Thread("Initializer") { - @Override - public void run() { - fa = ForeignAccess.create(ForeignAccessSingleThreadedTest.this); - } - }; - t.start(); - t.join(); - } - - @Test(expected = AssertionError.class) - public void accessNodeFromWrongThread() { - Node n = Message.IS_EXECUTABLE.createNode(); - Object ret = ForeignAccess.execute(n, null, this); - fail("Should throw an exception: " + ret); - } - - @After - public void noCallsToFactory() { - assertEquals("No calls to accessMessage or canHandle", 0, cnt); - } - - @Override - public boolean canHandle(TruffleObject obj) { - cnt++; - return true; - } - - @Override - public CallTarget accessMessage(Message tree) { - cnt++; - return null; - } - - @Override - public ForeignAccess getForeignAccess() { - return fa; - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/ForeignAccessToStringTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/ForeignAccessToStringTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.interop; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.TruffleObject; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class ForeignAccessToStringTest { - @Test - public void checkRegularFactory() { - ForeignAccess fa = ForeignAccess.create(new SimpleTestingFactory()); - assertEquals("ForeignAccess[com.oracle.truffle.api.test.interop.ForeignAccessToStringTest$SimpleTestingFactory]", fa.toString()); - } - - @Test - public void check10Factory() { - ForeignAccess fa = ForeignAccess.create(TruffleObject.class, new Simple10TestingFactory()); - assertEquals("ForeignAccess[com.oracle.truffle.api.test.interop.ForeignAccessToStringTest$Simple10TestingFactory]", fa.toString()); - } - - private static class SimpleTestingFactory implements ForeignAccess.Factory { - public SimpleTestingFactory() { - } - - @Override - public boolean canHandle(TruffleObject obj) { - return false; - } - - @Override - public CallTarget accessMessage(Message tree) { - return null; - } - } - - private static class Simple10TestingFactory implements ForeignAccess.Factory10 { - @Override - public CallTarget accessIsNull() { - return null; - } - - @Override - public CallTarget accessIsExecutable() { - return null; - } - - @Override - public CallTarget accessIsBoxed() { - return null; - } - - @Override - public CallTarget accessHasSize() { - return null; - } - - @Override - public CallTarget accessGetSize() { - return null; - } - - @Override - public CallTarget accessUnbox() { - return null; - } - - @Override - public CallTarget accessRead() { - return null; - } - - @Override - public CallTarget accessWrite() { - return null; - } - - @Override - public CallTarget accessExecute(int argumentsLength) { - return null; - } - - @Override - public CallTarget accessInvoke(int argumentsLength) { - return null; - } - - @Override - public CallTarget accessMessage(Message unknown) { - return null; - } - - @Override - public CallTarget accessNew(int argumentsLength) { - return null; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/MessageStringTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/interop/MessageStringTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.interop; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Locale; - -import org.junit.Test; - -import com.oracle.truffle.api.interop.Message; - -public class MessageStringTest { - - @Test - public void testFields() throws Exception { - for (Field f : Message.class.getFields()) { - if (f.getType() != Message.class) { - continue; - } - if ((f.getModifiers() & Modifier.STATIC) == 0) { - continue; - } - Message msg = (Message) f.get(null); - - String persistent = Message.toString(msg); - assertNotNull("Found name for " + f, persistent); - assertEquals("It is in upper case", persistent, persistent.toUpperCase(Locale.ENGLISH)); - - Message newMsg = Message.valueOf(persistent); - - assertSame("Same for " + f, msg, newMsg); - - assertEquals("Same toString()", persistent, msg.toString()); - } - } - - @Test - public void testFactoryMethods() throws Exception { - for (Method m : Message.class.getMethods()) { - if (m.getReturnType() != Message.class) { - continue; - } - if (!m.getName().startsWith("create")) { - continue; - } - if ((m.getModifiers() & Modifier.STATIC) == 0) { - continue; - } - Message msg = (Message) m.invoke(null, 0); - - String persistent = Message.toString(msg); - assertNotNull("Found name for " + m, persistent); - assertEquals("It is in upper case", persistent, persistent.toUpperCase(Locale.ENGLISH)); - - Message newMsg = Message.valueOf(persistent); - - assertEquals("Same for " + m, msg, newMsg); - - assertEquals("Same toString()", persistent, msg.toString()); - assertEquals("Same toString() for new one", persistent, newMsg.toString()); - } - } - - @Test - public void specialMessagePersitance() { - SpecialMsg msg = new SpecialMsg(); - String persistent = Message.toString(msg); - Message newMsg = Message.valueOf(persistent); - assertEquals("Message reconstructed", msg, newMsg); - } - - public static final class SpecialMsg extends Message { - - @Override - public boolean equals(Object message) { - return message instanceof SpecialMsg; - } - - @Override - public int hashCode() { - return 5425432; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/NodeUtilTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/NodeUtilTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 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.test.nodes; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeUtil; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.TestingLanguage; -import java.util.Iterator; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import org.junit.Test; - -public class NodeUtilTest { - - @Test - public void testRecursiveIterator1() { - TestRootNode root = new TestRootNode(); - root.child0 = new TestNode(); - root.adoptChildren(); - - int count = iterate(NodeUtil.makeRecursiveIterator(root)); - - assertThat(count, is(2)); - assertThat(root.visited, is(0)); - assertThat(root.child0.visited, is(1)); - } - - private static int iterate(Iterator iterator) { - int iterationCount = 0; - while (iterator.hasNext()) { - Node node = iterator.next(); - if (node == null) { - continue; - } - if (node instanceof TestNode) { - ((TestNode) node).visited = iterationCount; - } else if (node instanceof TestRootNode) { - ((TestRootNode) node).visited = iterationCount; - } else { - throw new AssertionError(); - } - iterationCount++; - } - return iterationCount; - } - - private static class TestNode extends Node { - - @Child TestNode child0; - @Child TestNode child1; - - private int visited; - - public TestNode() { - } - - } - - private static class TestRootNode extends RootNode { - - @Child TestNode child0; - - private int visited; - - public TestRootNode() { - super(TestingLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - return null; - } - - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/SafeReplaceTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/SafeReplaceTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2015, 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.test.nodes; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.test.TestingLanguage; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -/** - * Tests optional method for ensuring that a node replacement is type safe. Ordinary node - * replacement is performed by unsafe assignment of a parent node's child field. - */ -public class SafeReplaceTest { - - @Test - public void testCorrectReplacement() { - TestRootNode root = new TestRootNode(); - final TestNode oldChild = new TestNode(); - final TestNode newChild = new TestNode(); - root.child = oldChild; - assertFalse(oldChild.isSafelyReplaceableBy(newChild)); // No parent node - root.adoptChildren(); - assertTrue(oldChild.isSafelyReplaceableBy(newChild)); // Now adopted by parent - // new node - oldChild.replace(newChild); - root.execute(null); - assertEquals(root.executed, 1); - assertEquals(oldChild.executed, 0); - assertEquals(newChild.executed, 1); - } - - @Test - public void testIncorrectReplacement() { - TestRootNode root = new TestRootNode(); - final TestNode oldChild = new TestNode(); - root.child = oldChild; - root.adoptChildren(); - final TestNode newChild = new TestNode(); - final TestNode strayChild = new TestNode(); - assertFalse(strayChild.isSafelyReplaceableBy(newChild)); // Stray not a child of parent - final WrongTestNode wrongTypeNewChild = new WrongTestNode(); - assertFalse(oldChild.isSafelyReplaceableBy(wrongTypeNewChild)); - } - - private static class TestNode extends Node { - - private int executed; - - public Object execute() { - executed++; - return null; - } - } - - private static class TestRootNode extends RootNode { - - @Child TestNode child; - - private int executed; - - public TestRootNode() { - super(TestingLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - executed++; - child.execute(); - return null; - } - } - - private static class WrongTestNode extends Node { - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package.html --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package.html Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ - - - -

- This package contains basic tests of the Truffle API and serves at the same time as an - introduction to the Truffle API for language implementors. Every test gives an example on how to - use the construct explained in the class description. -

- -

- Truffle is a language implementation framework. A guest language method is represented as a tree - of executable nodes. The framework provides mechanisms for those trees to call each other. - Additionally it contains dedicated data structures for storing data local to a tree invocation. -

- -

- This introduction to Truffle contains items in the following recommended order: - -

    -
  • How to get access to the Truffle runtime? - {@link com.oracle.truffle.api.test.TruffleRuntimeTest}
  • -
  • How to create a root node? {@link com.oracle.truffle.api.test.RootNodeTest}
  • -
  • How to create a child node and link it with its parent? - {@link com.oracle.truffle.api.test.ChildNodeTest}
  • -
  • How to create an array of child nodes? {@link com.oracle.truffle.api.test.ChildrenNodesTest} -
  • -
  • Why are final fields in node classes important? - {@link com.oracle.truffle.api.test.FinalFieldTest}
  • -
  • How to replace one node with another node and what for? - {@link com.oracle.truffle.api.test.ReplaceTest}
  • -
  • How to let one Truffle tree invoke another one? {@link com.oracle.truffle.api.test.CallTest} -
  • -
  • How to pass arguments when executing a tree? - {@link com.oracle.truffle.api.test.ArgumentsTest}
  • -
  • How to use frames and frame slots to store values local to an activation? - {@link com.oracle.truffle.api.test.FrameTest}
  • -
  • How to use type specialization and speculation for frame slots? - {@link com.oracle.truffle.api.test.FrameSlotTypeSpecializationTest}
  • -
  • How to use type specialization and speculation for node return values? - {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}
  • -
  • How to "instrument" an AST with nodes that can provide access to runtime state from external - tools {@code com.oracle.truffle.api.test.instrument.InstrumentationTest}
  • -
- diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/BytesSourceSectionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/BytesSourceSectionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 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.test.source; - -import com.oracle.truffle.api.source.Source; -import java.nio.charset.StandardCharsets; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class BytesSourceSectionTest { - - @Test - public void testSectionsFromLineNumberASCII() { - final byte[] bytes = "foo\nbar\nbaz\n".getBytes(StandardCharsets.US_ASCII); - final Source source = Source.fromBytes(bytes, "description", StandardCharsets.US_ASCII); - assertEquals("foo", source.createSection("identifier", 1).getCode()); - assertEquals("bar", source.createSection("identifier", 2).getCode()); - assertEquals("baz", source.createSection("identifier", 3).getCode()); - } - - @Test - public void testSectionsFromOffsetsASCII() { - final byte[] bytes = "foo\nbar\nbaz\n".getBytes(StandardCharsets.US_ASCII); - final Source source = Source.fromBytes(bytes, "description", StandardCharsets.US_ASCII); - assertEquals("foo", source.createSection("identifier", 0, 3).getCode()); - assertEquals("bar", source.createSection("identifier", 4, 3).getCode()); - assertEquals("baz", source.createSection("identifier", 8, 3).getCode()); - } - - @Test - public void testOffset() { - final byte[] bytes = "xxxfoo\nbar\nbaz\nxxx".getBytes(StandardCharsets.US_ASCII); - final Source source = Source.fromBytes(bytes, 3, bytes.length - 6, "description", StandardCharsets.US_ASCII); - assertEquals("foo", source.createSection("identifier", 0, 3).getCode()); - assertEquals("bar", source.createSection("identifier", 4, 3).getCode()); - assertEquals("baz", source.createSection("identifier", 8, 3).getCode()); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/JavaRecognizer.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/JavaRecognizer.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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.test.source; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.spi.FileTypeDetector; - -public final class JavaRecognizer extends FileTypeDetector { - @Override - public String probeContentType(Path path) throws IOException { - if (path.getFileName().toString().endsWith(".java")) { - return "text/x-java"; - } - return null; - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceSectionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceSectionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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.test.source; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.SourceSection; - -public class SourceSectionTest { - - private final Source emptySource = Source.fromText("", null); - - private final Source emptyLineSource = Source.fromText("\n", null); - - private final Source shortSource = Source.fromText("01", null); - - private final Source longSource = Source.fromText("01234\n67\n9\n", "long"); - - public void emptySourceTest0() { - SourceSection section = emptySource.createSection("test", 0, 0); - assertNotNull(section); - assertEquals(section.getCode(), ""); - } - - @Test - public void emptyLineTest0() { - SourceSection section = emptyLineSource.createSection("test", 0, 0); - assertNotNull(section); - assertEquals(section.getCode(), ""); - assertEquals(section.getCharIndex(), 0); - assertEquals(section.getCharLength(), 0); - assertEquals(section.getStartLine(), 1); - assertEquals(section.getStartColumn(), 1); - } - - @Test - public void emptyLineTest1() { - SourceSection section = emptyLineSource.createSection("test", 0, 1); - assertNotNull(section); - assertEquals(section.getCode(), "\n"); - assertEquals(section.getCharIndex(), 0); - assertEquals(section.getCharLength(), 1); - assertEquals(section.getStartLine(), 1); - assertEquals(section.getStartColumn(), 1); - assertEquals(section.getEndLine(), 1); - assertEquals(section.getEndColumn(), 1); - } - - @Test - public void emptySectionTest2() { - SourceSection section = shortSource.createSection("test", 0, 0); - assertNotNull(section); - assertEquals(section.getCode(), ""); - } - - @Test - public void emptySectionTest3() { - SourceSection section = longSource.createSection("test", 0, 0); - assertNotNull(section); - assertEquals(section.getCode(), ""); - } - - @Test - public void testGetCode() { - assertEquals("01234", longSource.createSection("test", 0, 5).getCode()); - assertEquals("67", longSource.createSection("test", 6, 2).getCode()); - assertEquals("9", longSource.createSection("test", 9, 1).getCode()); - } - - @Test - public void testGetShortDescription() { - assertEquals("long:1", longSource.createSection("test", 0, 5).getShortDescription()); - assertEquals("long:2", longSource.createSection("test", 6, 2).getShortDescription()); - assertEquals("long:3", longSource.createSection("test", 9, 1).getShortDescription()); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange1() { - longSource.createSection("test", 9, 5); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange2() { - longSource.createSection("test", -1, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange3() { - longSource.createSection("test", 1, -1); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange4() { - longSource.createSection("test", 3, 1, 9, 5); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange5() { - longSource.createSection("test", 1, 1, -1, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testOutOfRange6() { - longSource.createSection("test", 1, 1, 1, -1); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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.test.source; - -import com.oracle.truffle.api.source.Source; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import org.junit.Test; - -public class SourceTest { - @Test - public void assignMimeTypeAndIdentity() { - Source s1 = Source.fromText("// a comment\n", "Empty comment"); - assertNull("No mime type assigned", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForApppendable() { - Source s1 = Source.fromAppendableText(""); - assertNull("No mime type assigned", s1.getMimeType()); - s1.appendCode("// Hello"); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForBytes() { - String text = "// Hello"; - Source s1 = Source.fromBytes(text.getBytes(StandardCharsets.UTF_8), "Hello", StandardCharsets.UTF_8); - assertNull("No mime type assigned", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForReader() throws IOException { - String text = "// Hello"; - Source s1 = Source.fromReader(new StringReader(text), "Hello"); - assertNull("No mime type assigned", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForFile() throws IOException { - File file = File.createTempFile("Hello", ".java"); - file.deleteOnExit(); - - String text; - try (FileWriter w = new FileWriter(file)) { - text = "// Hello"; - w.write(text); - } - - // JDK8 default fails on OS X: https://bugs.openjdk.java.net/browse/JDK-8129632 - Source s1 = Source.fromFileName(file.getPath()).withMimeType("text/x-java"); - assertEquals("Recognized as Java", "text/x-java", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForVirtualFile() throws IOException { - File file = File.createTempFile("Hello", ".java"); - file.deleteOnExit(); - - String text = "// Hello"; - - // JDK8 default fails on OS X: https://bugs.openjdk.java.net/browse/JDK-8129632 - Source s1 = Source.fromFileName(text, file.getPath()).withMimeType("text/x-java"); - assertEquals("Recognized as Java", "text/x-java", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } - - @Test - public void assignMimeTypeAndIdentityForURL() throws IOException { - File file = File.createTempFile("Hello", ".java"); - file.deleteOnExit(); - - String text; - try (FileWriter w = new FileWriter(file)) { - text = "// Hello"; - w.write(text); - } - - Source s1 = Source.fromURL(file.toURI().toURL(), "Hello.java"); - assertEquals("Threated as plain", "text/plain", s1.getMimeType()); - Source s2 = s1.withMimeType("text/x-c"); - assertEquals("They have the same content", s1.getCode(), s2.getCode()); - assertEquals("// Hello", s1.getCode()); - assertNotEquals("But different type", s1.getMimeType(), s2.getMimeType()); - assertNotEquals("So they are different", s1, s2); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTextTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTextTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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.test.source; - -import com.oracle.truffle.api.source.Source; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class SourceTextTest { - - private final Source emptySource = Source.fromText("", null); - - private final Source emptyLineSource = Source.fromText("\n", null); - - private final Source shortSource = Source.fromText("01", null); - - private final Source longSource = Source.fromText("01234\n67\n9\n", null); - - @Test - public void emptyTextTest0() { - assertEquals(emptySource.getLineCount(), 0); - } - - // Temp disable of empty text tests - - // @Test(expected = IllegalArgumentException.class) - @Test() - public void emptyTextTest1() { - emptySource.getLineNumber(0); - } - - // @Test(expected = IllegalArgumentException.class) - @Test() - public void emptyTextTest2() { - emptySource.getColumnNumber(0); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyTextTest3() { - emptySource.getLineNumber(-1); - } - - // @Test(expected = IllegalArgumentException.class) - @Test() - public void emptyTextTest4() { - emptySource.getLineStartOffset(0); - } - - // @Test(expected = IllegalArgumentException.class) - public void emptyTextTest5() { - emptySource.getLineStartOffset(1); - } - - // @Test(expected = IllegalArgumentException.class) - public void emptyTextTest6() { - emptySource.getLineLength(1); - } - - @Test - public void emptyLineTest0() { - assertEquals(emptyLineSource.getLineCount(), 1); - assertEquals(emptyLineSource.getLineNumber(0), 1); - assertEquals(emptyLineSource.getLineStartOffset(1), 0); - assertEquals(emptyLineSource.getColumnNumber(0), 1); - assertEquals(emptyLineSource.getLineLength(1), 0); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyLineTest1() { - emptyLineSource.getLineNumber(1); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyLineTest2() { - emptyLineSource.getLineStartOffset(2); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyLineTest3() { - emptyLineSource.getColumnNumber(1); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyLineTest4() { - emptyLineSource.getLineLength(2); - } - - @Test - public void shortTextTest0() { - - assertEquals(shortSource.getLineCount(), 1); - - assertEquals(shortSource.getLineNumber(0), 1); - assertEquals(shortSource.getLineStartOffset(1), 0); - assertEquals(shortSource.getColumnNumber(0), 1); - - assertEquals(shortSource.getLineNumber(1), 1); - assertEquals(shortSource.getColumnNumber(1), 2); - - assertEquals(shortSource.getLineLength(1), 2); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest1() { - shortSource.getLineNumber(-1); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest2() { - shortSource.getColumnNumber(-1); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest3() { - shortSource.getLineNumber(2); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest4() { - shortSource.getColumnNumber(2); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest5() { - shortSource.getLineLength(2); - } - - @Test(expected = IllegalArgumentException.class) - public void shortTextTest6() { - shortSource.getLineLength(2); - } - - @Test - public void longTextTest0() { - - assertEquals(longSource.getLineCount(), 3); - - assertEquals(longSource.getLineNumber(0), 1); - assertEquals(longSource.getLineStartOffset(1), 0); - assertEquals(longSource.getColumnNumber(0), 1); - - assertEquals(longSource.getLineNumber(4), 1); - assertEquals(longSource.getColumnNumber(4), 5); - - assertEquals(longSource.getLineNumber(5), 1); // newline - assertEquals(longSource.getColumnNumber(5), 6); // newline - assertEquals(longSource.getLineLength(1), 5); - - assertEquals(longSource.getLineNumber(6), 2); - assertEquals(longSource.getLineStartOffset(2), 6); - assertEquals(longSource.getColumnNumber(6), 1); - - assertEquals(longSource.getLineNumber(7), 2); - assertEquals(longSource.getColumnNumber(7), 2); - - assertEquals(longSource.getLineNumber(8), 2); // newline - assertEquals(longSource.getLineNumber(8), 2); // newline - assertEquals(longSource.getLineLength(2), 2); - - assertEquals(longSource.getLineNumber(9), 3); - assertEquals(longSource.getLineStartOffset(3), 9); - assertEquals(longSource.getColumnNumber(9), 1); - - assertEquals(longSource.getLineNumber(10), 3); // newline - assertEquals(longSource.getColumnNumber(10), 2); // newline - assertEquals(longSource.getLineLength(3), 1); - - } - - @Test(expected = IllegalArgumentException.class) - public void longTextTest1() { - longSource.getLineNumber(11); - } - - @Test(expected = IllegalArgumentException.class) - public void longTextTest2() { - longSource.getColumnNumber(11); - } - - @Test(expected = IllegalArgumentException.class) - public void longTextTest3() { - longSource.getLineStartOffset(4); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AlwaysValidAssumptionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AlwaysValidAssumptionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, 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.test.utilities; - -import com.oracle.truffle.api.nodes.InvalidAssumptionException; -import com.oracle.truffle.api.utilities.AlwaysValidAssumption; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class AlwaysValidAssumptionTest { - - @Test - public void testCheck() throws InvalidAssumptionException { - final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; - assumption.check(); - } - - @Test - public void testIsValid() { - final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; - assertTrue(assumption.isValid()); - } - - @Test(expected = UnsupportedOperationException.class) - public void testCannotInvalidate() { - final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; - assumption.invalidate(); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AssumedValueTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AssumedValueTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013, 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.test.utilities; - -import com.oracle.truffle.api.utilities.AssumedValue; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class AssumedValueTest { - - @Test - public void testGet() { - final AssumedValue assumedValue = new AssumedValue<>("assumed-value", "1"); - assertEquals("1", assumedValue.get()); - } - - @Test - public void testSet() { - final AssumedValue assumedValue = new AssumedValue<>("assumed-value", "1"); - assertEquals("1", assumedValue.get()); - assumedValue.set("2"); - assertEquals("2", assumedValue.get()); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BinaryConditionProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BinaryConditionProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014, 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.test.utilities; - -import com.oracle.truffle.api.utilities.BinaryConditionProfile; -import com.oracle.truffle.api.utilities.ConditionProfile; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class BinaryConditionProfileTest { - - @DataPoints public static boolean[] data = new boolean[]{true, false}; - - private BinaryConditionProfile profile; - - @Before - public void create() { - profile = (BinaryConditionProfile) ConditionProfile.createBinaryProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.wasTrue(), is(false)); - assertThat(profile.wasFalse(), is(false)); - } - - @Theory - public void testProfileOne(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertThat(profile.wasTrue(), is(value)); - assertThat(profile.wasFalse(), is(!value)); - } - - @Theory - public void testProfileTwo(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(profile.wasTrue(), is(value0 || value1)); - assertThat(profile.wasFalse(), is(!value0 || !value1)); - } - - @Theory - public void testProfileThree(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - assertThat(profile.wasTrue(), is(value0 || value1 || value2)); - assertThat(profile.wasFalse(), is(!value0 || !value1 || !value2)); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BranchProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BranchProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, 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.test.utilities; - -import com.oracle.truffle.api.utilities.BranchProfile; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class BranchProfileTest { - - @Test - public void testEnter() { - BranchProfile profile = BranchProfile.create(); - profile.enter(); - profile.enter(); - } - - @Test - public void testToString() { - BranchProfile profile = BranchProfile.create(); - assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); - assertTrue(profile.toString().contains("not-visited")); - assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); - profile.enter(); - assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); - assertTrue(profile.toString().contains("visited")); - assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CountingConditionProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CountingConditionProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014, 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.test.utilities; - -import com.oracle.truffle.api.utilities.ConditionProfile; -import com.oracle.truffle.api.utilities.CountingConditionProfile; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class CountingConditionProfileTest { - - @DataPoints public static boolean[] data = new boolean[]{true, false}; - - private CountingConditionProfile profile; - - @Before - public void create() { - profile = (CountingConditionProfile) ConditionProfile.createCountingProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.getTrueCount(), is(0)); - assertThat(profile.getFalseCount(), is(0)); - } - - @Theory - public void testProfileOne(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertThat(profile.getTrueCount(), is(value ? 1 : 0)); - assertThat(profile.getFalseCount(), is(!value ? 1 : 0)); - } - - @Theory - public void testProfileTwo(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0))); - assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0))); - } - - @Theory - public void testProfileThree(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0) + (value2 ? 1 : 0))); - assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0) + (!value2 ? 1 : 0))); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CyclicAssumptionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CyclicAssumptionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 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.test.utilities; - -import com.oracle.truffle.api.Assumption; -import com.oracle.truffle.api.utilities.CyclicAssumption; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class CyclicAssumptionTest { - - @Test - public void testIsValid() { - final CyclicAssumption assumption = new CyclicAssumption("cyclic-assumption"); - assertTrue(assumption.getAssumption().isValid()); - } - - @Test - public void testInvalidate() { - final CyclicAssumption cyclicAssumption = new CyclicAssumption("cyclic-assumption"); - - final Assumption firstAssumption = cyclicAssumption.getAssumption(); - assertEquals("cyclic-assumption", firstAssumption.getName()); - assertTrue(firstAssumption.isValid()); - - cyclicAssumption.invalidate(); - - assertFalse(firstAssumption.isValid()); - - final Assumption secondAssumption = cyclicAssumption.getAssumption(); - assertEquals("cyclic-assumption", secondAssumption.getName()); - assertTrue(secondAssumption.isValid()); - - cyclicAssumption.invalidate(); - - assertFalse(firstAssumption.isValid()); - assertFalse(secondAssumption.isValid()); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/ExactClassValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/ExactClassValueProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2014, 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.test.utilities; - -import com.oracle.truffle.api.utilities.ValueProfile; -import java.lang.reflect.Method; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class ExactClassValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = new String(); - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Integer O4 = new Integer(1); - @DataPoint public static final Integer O5 = null; - - private ValueProfile profile; - - @Before - public void create() { - profile = ValueProfile.createClassProfile(); - } - - @Test - public void testInitial() throws Exception { - assertThat(isGeneric(profile), is(false)); - assertThat(isUninitialized(profile), is(true)); - assertNull(getCachedClass(profile)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOne(Object value) throws Exception { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(getCachedClass(profile), expectedClass(value)); - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwo(Object value0, Object value1) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - Object expectedClass = expectedClass(value0) == expectedClass(value1) ? expectedClass(value0) : Object.class; - - assertEquals(getCachedClass(profile), expectedClass); - assertThat(isUninitialized(profile), is(false)); - assertThat(isGeneric(profile), is(expectedClass == Object.class)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; - - assertEquals(getCachedClass(profile), expectedClass); - assertThat(isUninitialized(profile), is(false)); - assertThat(isGeneric(profile), is(expectedClass == Object.class)); - profile.toString(); // test that it is not crashing - } - - private static Class expectedClass(Object value) { - return value == null ? Object.class : value.getClass(); - } - - private static Object get(String name, ValueProfile profile) throws Exception { - final Method m = profile.getClass().getDeclaredMethod(name); - m.setAccessible(true); - return m.invoke(profile); - } - - private static Object getCachedClass(ValueProfile profile) throws Exception { - return get("getCachedClass", profile); - } - - private static boolean isUninitialized(ValueProfile profile) throws Exception { - return (Boolean) get("isUninitialized", profile); - } - - private static boolean isGeneric(ValueProfile profile) throws Exception { - return (Boolean) get("isGeneric", profile); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/IdentityValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/IdentityValueProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2014, 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.test.utilities; - -import com.oracle.truffle.api.utilities.ValueProfile; -import java.lang.reflect.Method; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class IdentityValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = O1; - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Integer O4 = new Integer(1); - @DataPoint public static final Integer O5 = null; - - private ValueProfile profile; - - @Before - public void create() { - profile = ValueProfile.createIdentityProfile(); - } - - @Test - public void testInitial() throws Exception { - assertThat(isGeneric(profile), is(false)); - assertThat(isUninitialized(profile), is(true)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOne(Object value) throws Exception { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(getCachedValue(profile), value); - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwo(Object value0, Object value1) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - if (value0 == value1) { - assertThat(getCachedValue(profile), is(value0)); - assertThat(isGeneric(profile), is(false)); - } else { - assertThat(isGeneric(profile), is(true)); - } - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - if (value0 == value1 && value1 == value2) { - assertThat(getCachedValue(profile), is(value0)); - assertThat(isGeneric(profile), is(false)); - } else { - assertThat(isGeneric(profile), is(true)); - } - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - private static Object get(String name, ValueProfile profile) throws Exception { - final Method m = profile.getClass().getDeclaredMethod(name); - m.setAccessible(true); - return m.invoke(profile); - } - - private static Object getCachedValue(ValueProfile profile) throws Exception { - return get("getCachedValue", profile); - } - - private static boolean isUninitialized(ValueProfile profile) throws Exception { - return (Boolean) get("isUninitialized", profile); - } - - private static boolean isGeneric(ValueProfile profile) throws Exception { - return (Boolean) get("isGeneric", profile); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/InstrumentationTestMode.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/InstrumentationTestMode.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, 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.test.utilities; - -import static org.junit.Assert.fail; - -import java.lang.reflect.Field; - -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.vm.PolyglotEngine; - -public class InstrumentationTestMode { - - public static void set(boolean enable) { - - try { - final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); - final Field instrumenterField = vm.getClass().getDeclaredField("instrumenter"); - instrumenterField.setAccessible(true); - final Object instrumenter = instrumenterField.get(vm); - final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); - testVMField.setAccessible(true); - if (enable) { - testVMField.set(instrumenter, vm); - } else { - testVMField.set(instrumenter, null); - } - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { - fail("Reflective access to Instrumenter for testing"); - } - - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/NeverValidAssumptionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/NeverValidAssumptionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.test.utilities; - -import com.oracle.truffle.api.nodes.InvalidAssumptionException; -import com.oracle.truffle.api.utilities.NeverValidAssumption; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; -import org.junit.Test; - -public class NeverValidAssumptionTest { - - @Test - public void testCheck() { - final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; - - try { - assumption.check(); - fail(); - } catch (InvalidAssumptionException e) { - } catch (Exception e) { - fail(); - } - } - - @Test - public void testIsValid() { - final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; - assertFalse(assumption.isValid()); - } - - @Test - public void testInvalidateDoesNothing() { - final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; - assumption.invalidate(); - assumption.invalidate(); - assumption.invalidate(); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/PrimitiveValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/PrimitiveValueProfileTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,951 +0,0 @@ -/* - * Copyright (c) 2014, 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.test.utilities; - -import com.oracle.truffle.api.utilities.PrimitiveValueProfile; -import com.oracle.truffle.api.utilities.ValueProfile; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class PrimitiveValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = O1; - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Object O4 = null; - - @DataPoint public static final byte B1 = Byte.MIN_VALUE; - @DataPoint public static final byte B2 = 0; - @DataPoint public static final byte B3 = 14; - @DataPoint public static final byte B4 = Byte.MAX_VALUE; - - @DataPoint public static final short S1 = Short.MIN_VALUE; - @DataPoint public static final short S2 = 0; - @DataPoint public static final short S3 = 14; - @DataPoint public static final short S4 = Short.MAX_VALUE; - - @DataPoint public static final int I1 = Integer.MIN_VALUE; - @DataPoint public static final int I2 = 0; - @DataPoint public static final int I3 = 14; - @DataPoint public static final int I4 = Integer.MAX_VALUE; - - @DataPoint public static final long L1 = Long.MIN_VALUE; - @DataPoint public static final long L2 = 0; - @DataPoint public static final long L3 = 14; - @DataPoint public static final long L4 = Long.MAX_VALUE; - - @DataPoint public static final float F1 = Float.MIN_VALUE; - @DataPoint public static final float F2 = -0.0f; - @DataPoint public static final float F3 = +0.0f; - @DataPoint public static final float F4 = 14.5f; - @DataPoint public static final float F5 = Float.MAX_VALUE; - - @DataPoint public static final double D1 = Double.MIN_VALUE; - @DataPoint public static final double D2 = -0.0; - @DataPoint public static final double D3 = +0.0; - @DataPoint public static final double D4 = 14.5; - @DataPoint public static final double D5 = Double.MAX_VALUE; - - @DataPoint public static final boolean T1 = false; - @DataPoint public static final boolean T2 = true; - - @DataPoint public static final char C1 = Character.MIN_VALUE; - @DataPoint public static final char C2 = 0; - @DataPoint public static final char C3 = 14; - @DataPoint public static final char C4 = Character.MAX_VALUE; - - private static final float FLOAT_DELTA = 0.00001f; - private static final double DOUBLE_DELTA = 0.00001; - - private PrimitiveValueProfile profile; - - @Before - public void create() { - profile = ValueProfile.createPrimitiveProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.isGeneric(), is(false)); - assertThat(profile.isUninitialized(), is(true)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneObject(Object value) { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoObject(Object value0, Object value1) { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - if (value0 == value1) { - assertThat(profile.getCachedValue(), is(value0)); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeObject(Object value0, Object value1, Object value2) { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - if (value0 == value1 && value1 == value2) { - assertThat(profile.getCachedValue(), is(value0)); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneByte(byte value) { - byte result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoByte(byte value0, byte value1) { - byte result0 = profile.profile(value0); - byte result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Byte); - assertEquals((byte) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeByte(byte value0, byte value1, byte value2) { - byte result0 = profile.profile(value0); - byte result1 = profile.profile(value1); - byte result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Byte); - assertEquals((byte) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneShort(short value) { - short result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoShort(short value0, short value1) { - short result0 = profile.profile(value0); - short result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Short); - assertEquals((short) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeShort(short value0, short value1, short value2) { - short result0 = profile.profile(value0); - short result1 = profile.profile(value1); - short result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Short); - assertEquals((short) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneInteger(int value) { - int result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoInteger(int value0, int value1) { - int result0 = profile.profile(value0); - int result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Integer); - assertEquals((int) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeInteger(int value0, int value1, int value2) { - int result0 = profile.profile(value0); - int result1 = profile.profile(value1); - int result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Integer); - assertEquals((int) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneLong(long value) { - long result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoLong(long value0, long value1) { - long result0 = profile.profile(value0); - long result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Long); - assertEquals((long) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeLong(long value0, long value1, long value2) { - long result0 = profile.profile(value0); - long result1 = profile.profile(value1); - long result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Long); - assertEquals((long) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneFloat(float value) { - float result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoFloat(float value0, float value1) { - float result0 = profile.profile(value0); - float result1 = profile.profile(value1); - - assertEquals(result0, value0, FLOAT_DELTA); - assertEquals(result1, value1, FLOAT_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1)) { - assertTrue(profile.getCachedValue() instanceof Float); - assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeFloat(float value0, float value1, float value2) { - float result0 = profile.profile(value0); - float result1 = profile.profile(value1); - float result2 = profile.profile(value2); - - assertEquals(result0, value0, FLOAT_DELTA); - assertEquals(result1, value1, FLOAT_DELTA); - assertEquals(result2, value2, FLOAT_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { - assertTrue(profile.getCachedValue() instanceof Float); - assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneDouble(double value) { - double result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoDouble(double value0, double value1) { - double result0 = profile.profile(value0); - double result1 = profile.profile(value1); - - assertEquals(result0, value0, DOUBLE_DELTA); - assertEquals(result1, value1, DOUBLE_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1)) { - assertTrue(profile.getCachedValue() instanceof Double); - assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeDouble(double value0, double value1, double value2) { - double result0 = profile.profile(value0); - double result1 = profile.profile(value1); - double result2 = profile.profile(value2); - - assertEquals(result0, value0, DOUBLE_DELTA); - assertEquals(result1, value1, DOUBLE_DELTA); - assertEquals(result2, value2, DOUBLE_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { - assertTrue(profile.getCachedValue() instanceof Double); - assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneBoolean(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoBoolean(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Boolean); - assertEquals((boolean) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeBoolean(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Boolean); - assertEquals((boolean) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneChar(char value) { - char result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoChar(char value0, char value1) { - char result0 = profile.profile(value0); - char result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Character); - assertEquals((char) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeChar(char value0, char value1, char value2) { - char result0 = profile.profile(value0); - char result1 = profile.profile(value1); - char result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Character); - assertEquals((char) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testWithBoxedBoxedByte(byte value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Byte); - assertEquals((byte) result0, value); - assertTrue(result1 instanceof Byte); - assertEquals((byte) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedByte(byte value) { - byte result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Byte); - assertEquals((byte) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedByte(byte value) { - Object result0 = profile.profile((Object) value); - byte result1 = profile.profile(value); - - assertTrue(result0 instanceof Byte); - assertEquals((byte) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedShort(short value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Short); - assertEquals((short) result0, value); - assertTrue(result1 instanceof Short); - assertEquals((short) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedShort(short value) { - short result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Short); - assertEquals((short) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedShort(short value) { - Object result0 = profile.profile((Object) value); - short result1 = profile.profile(value); - - assertTrue(result0 instanceof Short); - assertEquals((short) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedInt(int value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Integer); - assertEquals((int) result0, value); - assertTrue(result1 instanceof Integer); - assertEquals((int) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedInt(int value) { - int result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Integer); - assertEquals((int) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedInt(int value) { - Object result0 = profile.profile((Object) value); - int result1 = profile.profile(value); - - assertTrue(result0 instanceof Integer); - assertEquals((int) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedLong(long value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Long); - assertEquals((long) result0, value); - assertTrue(result1 instanceof Long); - assertEquals((long) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedLong(long value) { - long result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Long); - assertEquals((long) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedLong(long value) { - Object result0 = profile.profile((Object) value); - long result1 = profile.profile(value); - - assertTrue(result0 instanceof Long); - assertEquals((long) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedFloat(float value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); - assertTrue(result1 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedFloat(float value) { - float result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); - assertTrue(result1 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedFloat(float value) { - Object result0 = profile.profile((Object) value); - float result1 = profile.profile(value); - - assertTrue(result0 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); - assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedDouble(double value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); - assertTrue(result1 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedDouble(double value) { - double result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); - assertTrue(result1 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedDouble(double value) { - Object result0 = profile.profile((Object) value); - double result1 = profile.profile(value); - - assertTrue(result0 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); - assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedBoolean(boolean value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Boolean); - assertEquals((boolean) result0, value); - assertTrue(result1 instanceof Boolean); - assertEquals((boolean) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedBoolean(boolean value) { - boolean result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Boolean); - assertEquals((boolean) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedBoolean(boolean value) { - Object result0 = profile.profile((Object) value); - boolean result1 = profile.profile(value); - - assertTrue(result0 instanceof Boolean); - assertEquals((boolean) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedChar(char value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Character); - assertEquals((char) result0, value); - assertTrue(result1 instanceof Character); - assertEquals((char) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedChar(char value) { - char result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Character); - assertEquals((char) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedCharacter(char value) { - Object result0 = profile.profile((Object) value); - char result1 = profile.profile(value); - - assertTrue(result0 instanceof Character); - assertEquals((char) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithByteThenObject(byte value0, Object value1) { - byte result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithShortThenObject(short value0, Object value1) { - short result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithIntThenObject(int value0, Object value1) { - int result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithLongThenObject(long value0, Object value1) { - long result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithFloatThenObject(float value0, Object value1) { - float result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithDoubleThenObject(double value0, Object value1) { - double result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithBooleanThenObject(boolean value0, Object value1) { - boolean result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithCharThenObject(char value0, Object value1) { - char result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Test - public void testNegativeZeroFloat() { - profile.profile(-0.0f); - profile.profile(+0.0f); - assertThat(profile.isGeneric(), is(true)); - } - - @Test - public void testNegativeZeroDouble() { - profile.profile(-0.0); - profile.profile(+0.0); - assertThat(profile.isGeneric(), is(true)); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/UnionAssumptionTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/UnionAssumptionTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2013, 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.test.utilities; - -import com.oracle.truffle.api.Assumption; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.nodes.InvalidAssumptionException; -import com.oracle.truffle.api.utilities.UnionAssumption; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class UnionAssumptionTest { - - @Test - public void testIsValid() { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - assertTrue(union.isValid()); - } - - @Test - public void testCheck() throws InvalidAssumptionException { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - union.check(); - } - - @Test - public void testFirstInvalidateIsValid() { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - first.invalidate(); - - assertFalse(union.isValid()); - } - - @Test(expected = InvalidAssumptionException.class) - public void testFirstInvalidateCheck() throws InvalidAssumptionException { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - first.invalidate(); - - union.check(); - } - - @Test - public void testSecondInvalidateIsValid() { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - second.invalidate(); - - assertFalse(union.isValid()); - } - - @Test(expected = InvalidAssumptionException.class) - public void testSecondInvalidateCheck() throws InvalidAssumptionException { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - second.invalidate(); - - union.check(); - } - - @Test - public void testBothInvalidateIsValid() { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - first.invalidate(); - second.invalidate(); - - assertFalse(union.isValid()); - } - - @Test(expected = InvalidAssumptionException.class) - public void testBothInvalidateCheck() throws InvalidAssumptionException { - final Assumption first = Truffle.getRuntime().createAssumption("first"); - final Assumption second = Truffle.getRuntime().createAssumption("second"); - final UnionAssumption union = new UnionAssumption(first, second); - - first.invalidate(); - second.invalidate(); - - union.check(); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.impl.Accessor; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.ExportImportLanguage1; -import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L1; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.concurrent.Executors; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.BeforeClass; -import org.junit.Test; - -public class AccessorTest { - public static Accessor API; - - @BeforeClass - public static void initAccessors() throws Exception { - Field f = Accessor.class.getDeclaredField("API"); - f.setAccessible(true); - API = (Accessor) f.get(null); - } - - @Test - public void canGetAccessToOwnLanguageInstance() throws Exception { - PolyglotEngine vm = PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()).build(); - PolyglotEngine.Language language = vm.getLanguages().get(L1); - assertNotNull("L1 language is defined", language); - - Source s = Source.fromText("return nothing", "nothing"); - Object ret = language.eval(s).get(); - assertNull("nothing is returned", ret); - - Object afterInitialization = findLanguageByClass(vm); - assertNotNull("Language found", afterInitialization); - assertTrue("Right instance: " + afterInitialization, afterInitialization instanceof ExportImportLanguage1); - } - - Object findLanguageByClass(PolyglotEngine vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { - Method find = Accessor.class.getDeclaredMethod("findLanguage", Object.class, Class.class); - find.setAccessible(true); - TruffleLanguage.Env env = (TruffleLanguage.Env) find.invoke(API, vm, ExportImportLanguage1.class); - Field f = env.getClass().getDeclaredField("langCtx"); - f.setAccessible(true); - Object langCtx = f.get(env); - f = langCtx.getClass().getDeclaredField("lang"); - f.setAccessible(true); - return f.get(langCtx); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ArrayTruffleObject.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ArrayTruffleObject.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.vm; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.RootNode; -import java.util.List; -import static org.junit.Assert.assertNotEquals; - -final class ArrayTruffleObject implements TruffleObject, ForeignAccess.Factory10 { - private final ForeignAccess access; - private final Object[] values; - private final Thread forbiddenDupl; - - ArrayTruffleObject(Object[] values) { - this(values, null); - } - - ArrayTruffleObject(Object[] values, Thread forbiddenDupl) { - this.access = forbiddenDupl == null ? ForeignAccess.create(getClass(), this) : null; - this.values = values; - this.forbiddenDupl = forbiddenDupl; - } - - @Override - public ForeignAccess getForeignAccess() { - return access != null ? access : ForeignAccess.create(getClass(), this); - } - - @Override - public CallTarget accessIsNull() { - return target(RootNode.createConstantNode(Boolean.FALSE)); - } - - @Override - public CallTarget accessIsExecutable() { - return target(RootNode.createConstantNode(Boolean.FALSE)); - } - - @Override - public CallTarget accessIsBoxed() { - return target(RootNode.createConstantNode(Boolean.FALSE)); - } - - @Override - public CallTarget accessHasSize() { - return target(RootNode.createConstantNode(Boolean.TRUE)); - } - - @Override - public CallTarget accessGetSize() { - return target(RootNode.createConstantNode(values.length)); - } - - @Override - public CallTarget accessUnbox() { - return null; - } - - @Override - public CallTarget accessRead() { - return target(new IndexNode()); - } - - @Override - public CallTarget accessWrite() { - return null; - } - - @Override - public CallTarget accessExecute(int argumentsLength) { - return null; - } - - @Override - public CallTarget accessInvoke(int argumentsLength) { - if (argumentsLength == 0) { - return target(new DuplNode()); - } - if (argumentsLength == 1) { - return target(new InvokeNode()); - } - return null; - } - - @Override - public CallTarget accessNew(int argumentsLength) { - return null; - } - - @Override - public CallTarget accessMessage(Message unknown) { - return null; - } - - private static CallTarget target(RootNode node) { - return Truffle.getRuntime().createCallTarget(node); - } - - private final class IndexNode extends RootNode { - public IndexNode() { - super(TruffleLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - int index = ((Number) ForeignAccess.getArguments(frame).get(0)).intValue(); - if (values[index] instanceof Object[]) { - return new ArrayTruffleObject((Object[]) values[index]); - } else { - return values[index]; - } - } - } - - private final class InvokeNode extends RootNode { - public InvokeNode() { - super(TruffleLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - final List args = ForeignAccess.getArguments(frame); - if (!"get".equals(args.get(0))) { - return null; - } - int index = ((Number) args.get(1)).intValue(); - if (values[index] instanceof Object[]) { - return new ArrayTruffleObject((Object[]) values[index]); - } else { - return values[index]; - } - } - } - - private final class DuplNode extends RootNode { - public DuplNode() { - super(TruffleLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - final List args = ForeignAccess.getArguments(frame); - if (!"dupl".equals(args.get(0))) { - return null; - } - assertNotEquals("Cannot allocate duplicate on forbidden thread", forbiddenDupl, Thread.currentThread()); - return new ArrayTruffleObject(values); - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineAsynchTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineAsynchTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.vm; - -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.util.concurrent.Executors; -import org.junit.Test; - -public class EngineAsynchTest extends EngineTest { - @Test - public void marker() { - } - - @Override - protected Thread forbiddenThread() { - return Thread.currentThread(); - } - - @Override - protected PolyglotEngine.Builder createBuilder() { - return PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineSingleThreadedTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineSingleThreadedTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.vm; - -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import org.junit.Before; -import org.junit.Test; - -public class EngineSingleThreadedTest { - PolyglotEngine tvm; - - @Before - public void initInDifferentThread() throws InterruptedException { - final PolyglotEngine.Builder b = PolyglotEngine.newBuilder(); - Thread t = new Thread("Initializer") { - @Override - public void run() { - tvm = b.build(); - } - }; - t.start(); - t.join(); - } - - @Test(expected = IllegalStateException.class) - public void evalURI() throws IOException { - tvm.eval(Source.fromURL(new File(".").toURI().toURL(), "wrong.test")); - } - - @Test(expected = IllegalStateException.class) - public void evalString() throws IOException { - tvm.eval(Source.fromText("1 + 1", "wrong.test").withMimeType("text/javascript")); - } - - @Test(expected = IllegalStateException.class) - public void evalReader() throws IOException { - try (StringReader sr = new StringReader("1 + 1")) { - tvm.eval(Source.fromReader(sr, "wrong.test").withMimeType("text/javascript")); - } - } - - @Test(expected = IllegalStateException.class) - public void evalSource() throws IOException { - tvm.eval(Source.fromText("", "Empty")); - } - - @Test(expected = IllegalStateException.class) - public void findGlobalSymbol() { - tvm.findGlobalSymbol("doesNotExists"); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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.test.vm; - -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.io.IOException; -import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.Test; - -public class EngineTest { - protected PolyglotEngine.Builder createBuilder() { - return PolyglotEngine.newBuilder(); - } - - @Test - public void npeWhenCastingAs() throws Exception { - PolyglotEngine tvm = createBuilder().build(); - - PolyglotEngine.Language language1 = tvm.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Language language2 = tvm.getLanguages().get("application/x-test-import-export-2"); - language2.eval(Source.fromText("explicit.value=42", "define 42")); - - PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); - String res = value.as(String.class); - assertNotNull(res); - } - - @Test - public void checkCachingOfNodes() throws IOException { - PolyglotEngine vm1 = createBuilder().build(); - PolyglotEngine vm2 = createBuilder().build(); - - PolyglotEngine.Language language1 = vm1.getLanguages().get("application/x-test-hash"); - PolyglotEngine.Language language2 = vm2.getLanguages().get("application/x-test-hash"); - PolyglotEngine.Language alt1 = vm1.getLanguages().get("application/x-test-hash-alt"); - PolyglotEngine.Language alt2 = vm2.getLanguages().get("application/x-test-hash-alt"); - final Source sharedSource = Source.fromText("anything", "something"); - - Object hashIn1Round1 = language1.eval(sharedSource).get(); - Object hashIn2Round1 = language2.eval(sharedSource).get(); - Object hashIn1Round2 = language1.eval(sharedSource).get(); - Object hashIn2Round2 = language2.eval(sharedSource).get(); - - Object altIn1Round1 = alt1.eval(sharedSource).get(); - Object altIn2Round1 = alt2.eval(sharedSource).get(); - Object altIn1Round2 = alt1.eval(sharedSource).get(); - Object altIn2Round2 = alt2.eval(sharedSource).get(); - - assertEquals("Two executions in 1st engine share the nodes", hashIn1Round1, hashIn1Round2); - assertEquals("Two executions in 2nd engine share the nodes", hashIn2Round1, hashIn2Round2); - - assertEquals("Two alternative executions in 1st engine share the nodes", altIn1Round1, altIn1Round2); - assertEquals("Two alternative executions in 2nd engine share the nodes", altIn2Round1, altIn2Round2); - - assertNotEquals("Two executions in different languages don't share the nodes", hashIn1Round1, altIn1Round1); - assertNotEquals("Two executions in different languages don't share the nodes", hashIn1Round1, altIn2Round1); - assertNotEquals("Two executions in different languages don't share the nodes", hashIn2Round2, altIn1Round2); - assertNotEquals("Two executions in different languages don't share the nodes", hashIn2Round2, altIn2Round2); - - assertNotEquals("Two executions in different engines don't share the nodes", hashIn1Round1, hashIn2Round1); - assertNotEquals("Two executions in different engines don't share the nodes", hashIn2Round2, hashIn1Round2); - } - - protected Thread forbiddenThread() { - return null; - } - - private interface AccessArray { - AccessArray dupl(); - - List get(int index); - } - - @Test - public void wrappedAsArray() throws Exception { - Object[][] matrix = {{1, 2, 3}}; - - PolyglotEngine tvm = createBuilder().globalSymbol("arr", new ArrayTruffleObject(matrix, forbiddenThread())).build(); - PolyglotEngine.Language language1 = tvm.getLanguages().get("application/x-test-import-export-1"); - AccessArray access = language1.eval(Source.fromText("return=arr", "get the array")).as(AccessArray.class); - assertNotNull("Array converted to list", access); - access = access.dupl(); - List list = access.get(0); - assertEquals("Size 3", 3, list.size()); - assertEquals(1, list.get(0)); - assertEquals(2, list.get(1)); - assertEquals(3, list.get(2)); - Integer[] arr = list.toArray(new Integer[0]); - assertEquals("Three items in array", 3, arr.length); - assertEquals(1, arr[0].intValue()); - assertEquals(2, arr[1].intValue()); - assertEquals(3, arr[2].intValue()); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ExceptionDuringParsingTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ExceptionDuringParsingTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import com.oracle.truffle.api.impl.Accessor; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.Ctx; -import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L1; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.io.IOException; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Test; - -public class ExceptionDuringParsingTest { - public static Accessor API; - - @Before - @After - public void cleanTheSet() { - Ctx.disposed.clear(); - } - - @Test - public void canGetAccessToOwnLanguageInstance() throws Exception { - PolyglotEngine vm = PolyglotEngine.newBuilder().build(); - PolyglotEngine.Language language = vm.getLanguages().get(L1); - assertNotNull("L1 language is defined", language); - - final Source src = Source.fromText("parse=No, no, no!", "Fail on parsing").withMimeType(L1); - try { - vm.eval(src); - fail("Exception thrown"); - } catch (IOException ex) { - assertEquals(ex.getMessage(), "No, no, no!"); - } - - assertEquals("No dispose yet", 0, Ctx.disposed.size()); - - vm.dispose(); - - assertEquals("One context disposed", 1, Ctx.disposed.size()); - - try { - vm.eval(src); - fail("Should throw an exception"); - } catch (IllegalStateException ex) { - assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); - } - try { - vm.findGlobalSymbol("nothing"); - fail("Should throw an exception"); - } catch (IllegalStateException ex) { - assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); - } - try { - vm.dispose(); - fail("Should throw an exception"); - } catch (IllegalStateException ex) { - assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolAsynchTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolAsynchTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import com.oracle.truffle.api.vm.PolyglotEngine; - -import java.util.concurrent.Executors; - -import org.junit.Test; - -public class GlobalSymbolAsynchTest extends GlobalSymbolTest { - @Test - public void marker() { - } - - @Override - protected PolyglotEngine.Builder createEngineBuilder() { - return PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.utilities.InstrumentationTestMode; - -import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L3; - -import com.oracle.truffle.api.vm.PolyglotEngine; - -import java.io.IOException; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class GlobalSymbolTest { - - @Before - public void before() { - InstrumentationTestMode.set(true); - } - - @After - public void after() { - InstrumentationTestMode.set(false); - } - - @Test - public void globalSymbolFoundByLanguage() throws IOException { - PolyglotEngine vm = createEngineBuilder().globalSymbol("ahoj", "42").build(); - // @formatter:off - Object ret = vm.eval( - Source.fromText("return=ahoj", "Return").withMimeType(L3) - ).get(); - // @formatter:on - assertEquals("42", ret); - } - - @Test - public void globalSymbolFoundByVMUser() throws IOException { - PolyglotEngine vm = createEngineBuilder().globalSymbol("ahoj", "42").build(); - PolyglotEngine.Value ret = vm.findGlobalSymbol("ahoj"); - assertNotNull("Symbol found", ret); - assertEquals("42", ret.get()); - } - - protected PolyglotEngine.Builder createEngineBuilder() { - return PolyglotEngine.newBuilder(); - } - - @Test - public void passingArray() throws IOException { - PolyglotEngine vm = createEngineBuilder().globalSymbol("arguments", new Object[]{"one", "two", "three"}).build(); - PolyglotEngine.Value value = vm.findGlobalSymbol("arguments"); - assertFalse("Not instance of array", value.get() instanceof Object[]); - assertTrue("Instance of TruffleObject", value.get() instanceof TruffleObject); - List args = value.as(List.class); - assertNotNull("Can be converted to List", args); - assertEquals("Three items", 3, args.size()); - assertEquals("one", args.get(0)); - assertEquals("two", args.get(1)); - assertEquals("three", args.get(2)); - String[] arr = args.toArray(new String[0]); - assertEquals("Three items in array", 3, arr.length); - assertEquals("one", arr[0]); - assertEquals("two", arr[1]); - assertEquals("three", arr[2]); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/HashLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/HashLanguage.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import java.io.IOException; - -@TruffleLanguage.Registration(name = "Hash", mimeType = "application/x-test-hash", version = "1.0") -public class HashLanguage extends TruffleLanguage { - public static final HashLanguage INSTANCE = new HashLanguage(); - - @Override - protected Env createContext(Env env) { - return env; - } - - @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - return Truffle.getRuntime().createCallTarget(new HashNode(this, code)); - } - - @Override - protected Object findExportedSymbol(Env context, String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal(Env context) { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected Visualizer getVisualizer() { - return null; - } - - @Override - protected boolean isInstrumentable(Node node) { - return false; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - throw new UnsupportedOperationException(); - } - - @Override - protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); // To change body of - // generated methods, choose - // Tools | Templates. - } - - private static class HashNode extends RootNode { - private static int counter; - private final Source code; - private final int id; - - public HashNode(HashLanguage hash, Source code) { - super(hash.getClass(), null, null); - this.code = code; - id = ++counter; - } - - @Override - public Object execute(VirtualFrame frame) { - return System.identityHashCode(this) + "@" + code.getCode() + " @ " + id; - } - } - - @TruffleLanguage.Registration(name = "AltHash", mimeType = "application/x-test-hash-alt", version = "1.0") - public static final class SubLang extends HashLanguage { - public static final SubLang INSTANCE = new SubLang(); - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2015, 2015, 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.test.vm; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.Reader; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.Executors; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.util.Objects; - -public class ImplicitExplicitExportTest { - private static Thread mainThread; - private PolyglotEngine vm; - - @Before - public void initializeVM() { - mainThread = Thread.currentThread(); - vm = PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()).build(); - assertTrue("Found " + L1 + " language", vm.getLanguages().containsKey(L1)); - assertTrue("Found " + L2 + " language", vm.getLanguages().containsKey(L2)); - assertTrue("Found " + L3 + " language", vm.getLanguages().containsKey(L3)); - } - - @After - public void cleanThread() { - mainThread = null; - } - - @Test - public void explicitExportFound() throws IOException { - // @formatter:off - vm.eval(Source.fromText("explicit.ahoj=42", "Fourty two").withMimeType(L1)); - Object ret = vm.eval( - Source.fromText("return=ahoj", "Return").withMimeType(L3) - ).get(); - // @formatter:on - assertEquals("42", ret); - } - - @Test - public void implicitExportFound() throws IOException { - // @formatter:off - vm.eval( - Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L1) - ); - Object ret = vm.eval( - Source.fromText("return=ahoj", "Return").withMimeType(L3) - ).get(); - // @formatter:on - assertEquals("42", ret); - } - - @Test - public void explicitExportPreferred2() throws IOException { - // @formatter:off - vm.eval( - Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L1) - ); - vm.eval( - Source.fromText("explicit.ahoj=43", "Fourty three").withMimeType(L2) - ); - Object ret = vm.eval( - Source.fromText("return=ahoj", "Return").withMimeType(L3) - ).get(); - // @formatter:on - assertEquals("Explicit import from L2 is used", "43", ret); - assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").get()); - } - - @Test - public void explicitExportPreferred1() throws IOException { - // @formatter:off - vm.eval( - Source.fromText("explicit.ahoj=43", "Fourty three").withMimeType(L1) - ); - vm.eval( - Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L2) - ); - Object ret = vm.eval( - Source.fromText("return=ahoj", "Return").withMimeType(L3) - ).get(); - // @formatter:on - assertEquals("Explicit import from L2 is used", "43", ret); - assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").invoke(null).get()); - } - - static final class Ctx { - static final Set disposed = new HashSet<>(); - - final Map explicit = new HashMap<>(); - final Map implicit = new HashMap<>(); - final Env env; - - public Ctx(Env env) { - this.env = env; - } - - void dispose() { - disposed.add(this); - } - } - - private abstract static class AbstractExportImportLanguage extends TruffleLanguage { - - @Override - protected Ctx createContext(Env env) { - if (mainThread != null) { - assertNotEquals("Should run asynchronously", Thread.currentThread(), mainThread); - } - return new Ctx(env); - } - - @Override - protected void disposeContext(Ctx context) { - context.dispose(); - } - - @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - if (code.getCode().startsWith("parse=")) { - throw new IOException(code.getCode().substring(6)); - } - return new ValueCallTarget(code, this); - } - - @Override - protected Object findExportedSymbol(Ctx context, String globalName, boolean onlyExplicit) { - if (context.explicit.containsKey(globalName)) { - return context.explicit.get(globalName); - } - if (!onlyExplicit && context.implicit.containsKey(globalName)) { - return context.implicit.get(globalName); - } - return null; - } - - @Override - protected Object getLanguageGlobal(Ctx context) { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected Visualizer getVisualizer() { - return null; - } - - @Override - protected boolean isInstrumentable(Node node) { - return false; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - return null; - } - - @Override - protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { - return null; - } - - private Object importExport(Source code) { - assertNotEquals("Should run asynchronously", Thread.currentThread(), mainThread); - final Node node = createFindContextNode(); - Ctx ctx = findContext(node); - Properties p = new Properties(); - try (Reader r = code.getReader()) { - p.load(r); - } catch (IOException ex) { - throw new IllegalStateException(ex); - } - Enumeration en = p.keys(); - while (en.hasMoreElements()) { - Object n = en.nextElement(); - if (n instanceof String) { - String k = (String) n; - if (k.startsWith("explicit.")) { - ctx.explicit.put(k.substring(9), p.getProperty(k)); - } - if (k.startsWith("implicit.")) { - ctx.implicit.put(k.substring(9), p.getProperty(k)); - } - if (k.equals("return")) { - return ctx.env.importSymbol(p.getProperty(k)); - } - } - } - return null; - } - } - - private static final class ValueCallTarget implements RootCallTarget { - private final Source code; - private final AbstractExportImportLanguage language; - - private ValueCallTarget(Source code, AbstractExportImportLanguage language) { - this.code = code; - this.language = language; - } - - @Override - public RootNode getRootNode() { - throw new UnsupportedOperationException(); - } - - @Override - public Object call(Object... arguments) { - return language.importExport(code); - } - } - - static final String L1 = "application/x-test-import-export-1"; - static final String L2 = "application/x-test-import-export-2"; - static final String L3 = "application/x-test-import-export-3"; - - @TruffleLanguage.Registration(mimeType = L1, name = "ImportExport1", version = "0") - public static final class ExportImportLanguage1 extends AbstractExportImportLanguage { - public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage1(); - - public ExportImportLanguage1() { - } - - @Override - protected String toString(Ctx ctx, Object value) { - if (value instanceof String) { - try { - int number = Integer.parseInt((String) value); - return number + ": Int"; - } catch (NumberFormatException ex) { - // go on - } - } - return Objects.toString(value); - } - } - - @TruffleLanguage.Registration(mimeType = L2, name = "ImportExport2", version = "0") - public static final class ExportImportLanguage2 extends AbstractExportImportLanguage { - public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage2(); - - public ExportImportLanguage2() { - } - - @Override - protected String toString(Ctx ctx, Object value) { - if (value instanceof String) { - try { - double number = Double.parseDouble((String) value); - return number + ": Double"; - } catch (NumberFormatException ex) { - // go on - } - } - return Objects.toString(value); - } - } - - @TruffleLanguage.Registration(mimeType = L3, name = "ImportExport3", version = "0") - public static final class ExportImportLanguage3 extends AbstractExportImportLanguage { - public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage3(); - - private ExportImportLanguage3() { - } - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.vm; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.lang.reflect.Field; - -import org.junit.Test; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.debug.Breakpoint; -import com.oracle.truffle.api.debug.Debugger; -import com.oracle.truffle.api.debug.ExecutionEvent; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.EventHandlerNode; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.StandardSyntaxTag; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.instrument.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeVisitor; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.vm.EventConsumer; -import com.oracle.truffle.api.vm.PolyglotEngine; - -/** - * Bug report validating test. - *

- * It has been reported that calling {@link Env#importSymbol(java.lang.String)} in - * {@link TruffleLanguage TruffleLanguage.createContext(env)} yields a {@link NullPointerException}. - *

- * The other report was related to specifying an abstract language class in the RootNode and - * problems with debugging later on. That is what the other part of this test - once it obtains - * Debugger instance simulates. - */ -public class InitializationTest { - - @Test - public void accessProbeForAbstractLanguage() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Debugger[] arr = {null}; - PolyglotEngine vm = PolyglotEngine.newBuilder().onEvent(new EventConsumer(ExecutionEvent.class) { - @Override - protected void on(ExecutionEvent event) { - arr[0] = event.getDebugger(); - } - }).build(); - - final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - final Instrumenter instrumenter = (Instrumenter) field.get(vm); - instrumenter.registerASTProber(new ASTProber() { - - public void probeAST(final Instrumenter inst, RootNode startNode) { - startNode.accept(new NodeVisitor() { - - public boolean visit(Node node) { - - if (node instanceof ANode) { - inst.probe(node).tagAs(StandardSyntaxTag.STATEMENT, null); - } - return true; - } - }); - } - }); - - Source source = Source.fromText("accessProbeForAbstractLanguage text", "accessProbeForAbstractLanguage").withMimeType("application/x-abstrlang"); - - assertEquals(vm.eval(source).get(), 1); - - assertNotNull("Debugger found", arr[0]); - - Debugger d = arr[0]; - Breakpoint b = d.setLineBreakpoint(0, source.createLineLocation(1), true); - assertTrue(b.isEnabled()); - b.setCondition("true"); - - assertEquals(vm.eval(source).get(), 1); - vm.dispose(); - } - - private static final class MMRootNode extends RootNode { - @Child ANode node; - - MMRootNode(SourceSection ss) { - super(AbstractLanguage.class, ss, null); - node = new ANode(42); - adoptChildren(); - } - - @Override - public Object execute(VirtualFrame frame) { - return node.constant(); - } - } - - private static class ANode extends Node { - private final int constant; - - public ANode(int constant) { - this.constant = constant; - } - - @Override - public SourceSection getSourceSection() { - return getRootNode().getSourceSection(); - } - - Object constant() { - return constant; - } - } - - private static class ANodeWrapper extends ANode implements WrapperNode { - @Child ANode child; - @Child private EventHandlerNode eventHandlerNode; - - ANodeWrapper(ANode node) { - super(1); // dummy - this.child = node; - } - - @Override - public Node getChild() { - return child; - } - - @Override - public Probe getProbe() { - return eventHandlerNode.getProbe(); - } - - @Override - public void insertEventHandlerNode(EventHandlerNode eventHandler) { - this.eventHandlerNode = eventHandler; - } - - @Override - public String instrumentationInfo() { - throw new UnsupportedOperationException(); - } - } - - private abstract static class AbstractLanguage extends TruffleLanguage { - } - - @TruffleLanguage.Registration(mimeType = "application/x-abstrlang", name = "AbstrLang", version = "0.1") - public static final class TestLanguage extends AbstractLanguage { - public static final TestLanguage INSTANCE = new TestLanguage(); - - @Override - protected Object createContext(Env env) { - assertNull("Not defined symbol", env.importSymbol("unknown")); - return env; - } - - @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - return Truffle.getRuntime().createCallTarget(new MMRootNode(code.createSection("1st line", 1))); - } - - @Override - protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal(Object context) { - throw new UnsupportedOperationException(); - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - throw new UnsupportedOperationException(); - } - - @Override - public Object evalInContext(Source source, Node node, MaterializedFrame mFrame) { - throw new UnsupportedOperationException(); - } - - @Override - public Visualizer getVisualizer() { - throw new UnsupportedOperationException(); - } - - @Override - protected boolean isInstrumentable(Node node) { - return node instanceof ANode; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - return node instanceof ANode ? new ANodeWrapper((ANode) node) : null; - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ToStringTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ToStringTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.vm; - -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class ToStringTest { - @Test - public void valueToStringValueWith1() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); - language2.eval(Source.fromText("explicit.value=42", "define 42")); - PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); - assertEquals("It's fourtytwo", "42", value.get()); - - String textual = value.as(String.class); - assertEquals("Nicely formated as by L1", "42: Int", textual); - } - - @Test - public void valueToStringValueWith2() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); - language1.eval(Source.fromText("explicit.value=42", "define 42")); - PolyglotEngine.Value value = language2.eval(Source.fromText("return=value", "42.value")); - assertEquals("It's fourtytwo", "42", value.get()); - - String textual = value.as(String.class); - assertEquals("Nicely formated as by L2", "42.0: Double", textual); - } - -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ValueTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ValueTest.java Tue Dec 01 11:13:11 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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.test.vm; - -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Executor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; - -public class ValueTest implements Executor { - private List pending = new LinkedList<>(); - - @Test - public void valueToStringValue() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); - language2.eval(Source.fromText("explicit.value=42", "define 42")); - PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); - assertEquals("It's fourtytwo", "42", value.get()); - - String textual = value.toString(); - assertTrue("Contains the value " + textual, textual.contains("value=42")); - assertTrue("Is computed " + textual, textual.contains("computed=true")); - assertTrue("No error " + textual, textual.contains("exception=null")); - } - - @Test - public void valueToStringException() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Value value = null; - try { - value = language1.eval(Source.fromText("parse=does not work", "error.value")); - Object res = value.get(); - fail("Should throw an exception: " + res); - } catch (IOException ex) { - assertTrue("Message contains the right text: " + ex.getMessage(), ex.getMessage().contains("does not work")); - } - - assertNull("No value returned", value); - } - - @Test - public void valueToStringValueAsync() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().executor(this).build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); - language2.eval(Source.fromText("explicit.value=42", "define 42")); - flush(); - - PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); - - String textual = value.toString(); - assertFalse("Doesn't contain the value " + textual, textual.contains("value=42")); - assertTrue("Is not computed " + textual, textual.contains("computed=false")); - assertTrue("No error " + textual, textual.contains("exception=null")); - assertTrue("No value yet " + textual, textual.contains("value=null")); - - flush(); - - textual = value.toString(); - assertTrue("Is computed " + textual, textual.contains("computed=true")); - assertTrue("No error " + textual, textual.contains("exception=null")); - assertTrue("value computed " + textual, textual.contains("value=42")); - } - - @Test - public void valueToStringExceptionAsync() throws Exception { - PolyglotEngine engine = PolyglotEngine.newBuilder().executor(this).build(); - PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); - PolyglotEngine.Value value = language1.eval(Source.fromText("parse=does not work", "error.value")); - assertNotNull("Value returned", value); - - String textual = value.toString(); - assertTrue("Is not computed " + textual, textual.contains("computed=false")); - assertTrue("No error " + textual, textual.contains("exception=null")); - assertTrue("No value yet " + textual, textual.contains("value=null")); - - flush(); - - textual = value.toString(); - assertTrue("Is computed " + textual, textual.contains("computed=true")); - assertTrue("No value at all" + textual, textual.contains("value=null")); - assertTrue("Error " + textual, textual.contains("exception=java.io.IOException: does not work")); - } - - @Override - public void execute(Runnable command) { - pending.add(command); - } - - private void flush() { - for (Runnable r : pending) { - r.run(); - } - } -} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/AlwaysValidAssumptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/AlwaysValidAssumptionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, 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.utilities; + +import com.oracle.truffle.api.nodes.InvalidAssumptionException; +import com.oracle.truffle.api.utilities.AlwaysValidAssumption; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class AlwaysValidAssumptionTest { + + @Test + public void testCheck() throws InvalidAssumptionException { + final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; + assumption.check(); + } + + @Test + public void testIsValid() { + final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; + assertTrue(assumption.isValid()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testCannotInvalidate() { + final AlwaysValidAssumption assumption = AlwaysValidAssumption.INSTANCE; + assumption.invalidate(); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/AssumedValueTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/AssumedValueTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 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.utilities; + +import com.oracle.truffle.api.utilities.AssumedValue; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class AssumedValueTest { + + @Test + public void testGet() { + final AssumedValue assumedValue = new AssumedValue<>("assumed-value", "1"); + assertEquals("1", assumedValue.get()); + } + + @Test + public void testSet() { + final AssumedValue assumedValue = new AssumedValue<>("assumed-value", "1"); + assertEquals("1", assumedValue.get()); + assumedValue.set("2"); + assertEquals("2", assumedValue.get()); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BinaryConditionProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BinaryConditionProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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.utilities; + +import com.oracle.truffle.api.utilities.BinaryConditionProfile; +import com.oracle.truffle.api.utilities.ConditionProfile; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class BinaryConditionProfileTest { + + @DataPoints public static boolean[] data = new boolean[]{true, false}; + + private BinaryConditionProfile profile; + + @Before + public void create() { + profile = (BinaryConditionProfile) ConditionProfile.createBinaryProfile(); + } + + @Test + public void testInitial() { + assertThat(profile.wasTrue(), is(false)); + assertThat(profile.wasFalse(), is(false)); + } + + @Theory + public void testProfileOne(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertThat(profile.wasTrue(), is(value)); + assertThat(profile.wasFalse(), is(!value)); + } + + @Theory + public void testProfileTwo(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(profile.wasTrue(), is(value0 || value1)); + assertThat(profile.wasFalse(), is(!value0 || !value1)); + } + + @Theory + public void testProfileThree(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + assertThat(profile.wasTrue(), is(value0 || value1 || value2)); + assertThat(profile.wasFalse(), is(!value0 || !value1 || !value2)); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BranchProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BranchProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, 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.utilities; + +import com.oracle.truffle.api.utilities.BranchProfile; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class BranchProfileTest { + + @Test + public void testEnter() { + BranchProfile profile = BranchProfile.create(); + profile.enter(); + profile.enter(); + } + + @Test + public void testToString() { + BranchProfile profile = BranchProfile.create(); + assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); + assertTrue(profile.toString().contains("not-visited")); + assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); + profile.enter(); + assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); + assertTrue(profile.toString().contains("visited")); + assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CountingConditionProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CountingConditionProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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.utilities; + +import com.oracle.truffle.api.utilities.ConditionProfile; +import com.oracle.truffle.api.utilities.CountingConditionProfile; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class CountingConditionProfileTest { + + @DataPoints public static boolean[] data = new boolean[]{true, false}; + + private CountingConditionProfile profile; + + @Before + public void create() { + profile = (CountingConditionProfile) ConditionProfile.createCountingProfile(); + } + + @Test + public void testInitial() { + assertThat(profile.getTrueCount(), is(0)); + assertThat(profile.getFalseCount(), is(0)); + } + + @Theory + public void testProfileOne(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertThat(profile.getTrueCount(), is(value ? 1 : 0)); + assertThat(profile.getFalseCount(), is(!value ? 1 : 0)); + } + + @Theory + public void testProfileTwo(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0))); + } + + @Theory + public void testProfileThree(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0) + (value2 ? 1 : 0))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0) + (!value2 ? 1 : 0))); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CyclicAssumptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CyclicAssumptionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 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.utilities; + +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.utilities.CyclicAssumption; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class CyclicAssumptionTest { + + @Test + public void testIsValid() { + final CyclicAssumption assumption = new CyclicAssumption("cyclic-assumption"); + assertTrue(assumption.getAssumption().isValid()); + } + + @Test + public void testInvalidate() { + final CyclicAssumption cyclicAssumption = new CyclicAssumption("cyclic-assumption"); + + final Assumption firstAssumption = cyclicAssumption.getAssumption(); + assertEquals("cyclic-assumption", firstAssumption.getName()); + assertTrue(firstAssumption.isValid()); + + cyclicAssumption.invalidate(); + + assertFalse(firstAssumption.isValid()); + + final Assumption secondAssumption = cyclicAssumption.getAssumption(); + assertEquals("cyclic-assumption", secondAssumption.getName()); + assertTrue(secondAssumption.isValid()); + + cyclicAssumption.invalidate(); + + assertFalse(firstAssumption.isValid()); + assertFalse(secondAssumption.isValid()); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, 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.utilities; + +import com.oracle.truffle.api.utilities.ValueProfile; +import java.lang.reflect.Method; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class ExactClassValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = new String(); + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Integer O4 = new Integer(1); + @DataPoint public static final Integer O5 = null; + + private ValueProfile profile; + + @Before + public void create() { + profile = ValueProfile.createClassProfile(); + } + + @Test + public void testInitial() throws Exception { + assertThat(isGeneric(profile), is(false)); + assertThat(isUninitialized(profile), is(true)); + assertNull(getCachedClass(profile)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOne(Object value) throws Exception { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(getCachedClass(profile), expectedClass(value)); + assertThat(isUninitialized(profile), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwo(Object value0, Object value1) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + Object expectedClass = expectedClass(value0) == expectedClass(value1) ? expectedClass(value0) : Object.class; + + assertEquals(getCachedClass(profile), expectedClass); + assertThat(isUninitialized(profile), is(false)); + assertThat(isGeneric(profile), is(expectedClass == Object.class)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; + + assertEquals(getCachedClass(profile), expectedClass); + assertThat(isUninitialized(profile), is(false)); + assertThat(isGeneric(profile), is(expectedClass == Object.class)); + profile.toString(); // test that it is not crashing + } + + private static Class expectedClass(Object value) { + return value == null ? Object.class : value.getClass(); + } + + private static Object get(String name, ValueProfile profile) throws Exception { + final Method m = profile.getClass().getDeclaredMethod(name); + m.setAccessible(true); + return m.invoke(profile); + } + + private static Object getCachedClass(ValueProfile profile) throws Exception { + return get("getCachedClass", profile); + } + + private static boolean isUninitialized(ValueProfile profile) throws Exception { + return (Boolean) get("isUninitialized", profile); + } + + private static boolean isGeneric(ValueProfile profile) throws Exception { + return (Boolean) get("isGeneric", profile); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/IdentityValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/IdentityValueProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, 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.utilities; + +import com.oracle.truffle.api.utilities.ValueProfile; +import java.lang.reflect.Method; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class IdentityValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = O1; + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Integer O4 = new Integer(1); + @DataPoint public static final Integer O5 = null; + + private ValueProfile profile; + + @Before + public void create() { + profile = ValueProfile.createIdentityProfile(); + } + + @Test + public void testInitial() throws Exception { + assertThat(isGeneric(profile), is(false)); + assertThat(isUninitialized(profile), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOne(Object value) throws Exception { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(getCachedValue(profile), value); + assertThat(isUninitialized(profile), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwo(Object value0, Object value1) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(getCachedValue(profile), is(value0)); + assertThat(isGeneric(profile), is(false)); + } else { + assertThat(isGeneric(profile), is(true)); + } + assertThat(isUninitialized(profile), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(getCachedValue(profile), is(value0)); + assertThat(isGeneric(profile), is(false)); + } else { + assertThat(isGeneric(profile), is(true)); + } + assertThat(isUninitialized(profile), is(false)); + profile.toString(); // test that it is not crashing + } + + private static Object get(String name, ValueProfile profile) throws Exception { + final Method m = profile.getClass().getDeclaredMethod(name); + m.setAccessible(true); + return m.invoke(profile); + } + + private static Object getCachedValue(ValueProfile profile) throws Exception { + return get("getCachedValue", profile); + } + + private static boolean isUninitialized(ValueProfile profile) throws Exception { + return (Boolean) get("isUninitialized", profile); + } + + private static boolean isGeneric(ValueProfile profile) throws Exception { + return (Boolean) get("isGeneric", profile); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/InstrumentationTestMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/InstrumentationTestMode.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 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.utilities; + +import static org.junit.Assert.fail; + +import java.lang.reflect.Field; + +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.vm.PolyglotEngine; + +public class InstrumentationTestMode { + + public static void set(boolean enable) { + + try { + final PolyglotEngine vm = PolyglotEngine.newBuilder().build(); + final Field instrumenterField = vm.getClass().getDeclaredField("instrumenter"); + instrumenterField.setAccessible(true); + final Object instrumenter = instrumenterField.get(vm); + final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); + testVMField.setAccessible(true); + if (enable) { + testVMField.set(instrumenter, vm); + } else { + testVMField.set(instrumenter, null); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + fail("Reflective access to Instrumenter for testing"); + } + + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/NeverValidAssumptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/NeverValidAssumptionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, 2014, 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.utilities; + +import com.oracle.truffle.api.nodes.InvalidAssumptionException; +import com.oracle.truffle.api.utilities.NeverValidAssumption; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; +import org.junit.Test; + +public class NeverValidAssumptionTest { + + @Test + public void testCheck() { + final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; + + try { + assumption.check(); + fail(); + } catch (InvalidAssumptionException e) { + } catch (Exception e) { + fail(); + } + } + + @Test + public void testIsValid() { + final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; + assertFalse(assumption.isValid()); + } + + @Test + public void testInvalidateDoesNothing() { + final NeverValidAssumption assumption = NeverValidAssumption.INSTANCE; + assumption.invalidate(); + assumption.invalidate(); + assumption.invalidate(); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/PrimitiveValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/PrimitiveValueProfileTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,951 @@ +/* + * Copyright (c) 2014, 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.utilities; + +import com.oracle.truffle.api.utilities.PrimitiveValueProfile; +import com.oracle.truffle.api.utilities.ValueProfile; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class PrimitiveValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = O1; + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Object O4 = null; + + @DataPoint public static final byte B1 = Byte.MIN_VALUE; + @DataPoint public static final byte B2 = 0; + @DataPoint public static final byte B3 = 14; + @DataPoint public static final byte B4 = Byte.MAX_VALUE; + + @DataPoint public static final short S1 = Short.MIN_VALUE; + @DataPoint public static final short S2 = 0; + @DataPoint public static final short S3 = 14; + @DataPoint public static final short S4 = Short.MAX_VALUE; + + @DataPoint public static final int I1 = Integer.MIN_VALUE; + @DataPoint public static final int I2 = 0; + @DataPoint public static final int I3 = 14; + @DataPoint public static final int I4 = Integer.MAX_VALUE; + + @DataPoint public static final long L1 = Long.MIN_VALUE; + @DataPoint public static final long L2 = 0; + @DataPoint public static final long L3 = 14; + @DataPoint public static final long L4 = Long.MAX_VALUE; + + @DataPoint public static final float F1 = Float.MIN_VALUE; + @DataPoint public static final float F2 = -0.0f; + @DataPoint public static final float F3 = +0.0f; + @DataPoint public static final float F4 = 14.5f; + @DataPoint public static final float F5 = Float.MAX_VALUE; + + @DataPoint public static final double D1 = Double.MIN_VALUE; + @DataPoint public static final double D2 = -0.0; + @DataPoint public static final double D3 = +0.0; + @DataPoint public static final double D4 = 14.5; + @DataPoint public static final double D5 = Double.MAX_VALUE; + + @DataPoint public static final boolean T1 = false; + @DataPoint public static final boolean T2 = true; + + @DataPoint public static final char C1 = Character.MIN_VALUE; + @DataPoint public static final char C2 = 0; + @DataPoint public static final char C3 = 14; + @DataPoint public static final char C4 = Character.MAX_VALUE; + + private static final float FLOAT_DELTA = 0.00001f; + private static final double DOUBLE_DELTA = 0.00001; + + private PrimitiveValueProfile profile; + + @Before + public void create() { + profile = ValueProfile.createPrimitiveProfile(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneObject(Object value) { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoObject(Object value0, Object value1) { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeObject(Object value0, Object value1, Object value2) { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneByte(byte value) { + byte result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoByte(byte value0, byte value1) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Byte); + assertEquals((byte) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeByte(byte value0, byte value1, byte value2) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + byte result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Byte); + assertEquals((byte) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneShort(short value) { + short result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoShort(short value0, short value1) { + short result0 = profile.profile(value0); + short result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Short); + assertEquals((short) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeShort(short value0, short value1, short value2) { + short result0 = profile.profile(value0); + short result1 = profile.profile(value1); + short result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Short); + assertEquals((short) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneInteger(int value) { + int result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoInteger(int value0, int value1) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Integer); + assertEquals((int) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeInteger(int value0, int value1, int value2) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + int result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Integer); + assertEquals((int) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneLong(long value) { + long result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoLong(long value0, long value1) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Long); + assertEquals((long) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeLong(long value0, long value1, long value2) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + long result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Long); + assertEquals((long) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneFloat(float value) { + float result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoFloat(float value0, float value1) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertTrue(profile.getCachedValue() instanceof Float); + assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeFloat(float value0, float value1, float value2) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + float result2 = profile.profile(value2); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + assertEquals(result2, value2, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertTrue(profile.getCachedValue() instanceof Float); + assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneDouble(double value) { + double result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoDouble(double value0, double value1) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + + assertEquals(result0, value0, DOUBLE_DELTA); + assertEquals(result1, value1, DOUBLE_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertTrue(profile.getCachedValue() instanceof Double); + assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeDouble(double value0, double value1, double value2) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + double result2 = profile.profile(value2); + + assertEquals(result0, value0, DOUBLE_DELTA); + assertEquals(result1, value1, DOUBLE_DELTA); + assertEquals(result2, value2, DOUBLE_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertTrue(profile.getCachedValue() instanceof Double); + assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneBoolean(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoBoolean(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Boolean); + assertEquals((boolean) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeBoolean(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Boolean); + assertEquals((boolean) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneChar(char value) { + char result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoChar(char value0, char value1) { + char result0 = profile.profile(value0); + char result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Character); + assertEquals((char) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeChar(char value0, char value1, char value2) { + char result0 = profile.profile(value0); + char result1 = profile.profile(value1); + char result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Character); + assertEquals((char) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testWithBoxedBoxedByte(byte value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Byte); + assertEquals((byte) result0, value); + assertTrue(result1 instanceof Byte); + assertEquals((byte) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedByte(byte value) { + byte result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Byte); + assertEquals((byte) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedByte(byte value) { + Object result0 = profile.profile((Object) value); + byte result1 = profile.profile(value); + + assertTrue(result0 instanceof Byte); + assertEquals((byte) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedShort(short value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Short); + assertEquals((short) result0, value); + assertTrue(result1 instanceof Short); + assertEquals((short) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedShort(short value) { + short result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Short); + assertEquals((short) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedShort(short value) { + Object result0 = profile.profile((Object) value); + short result1 = profile.profile(value); + + assertTrue(result0 instanceof Short); + assertEquals((short) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedInt(int value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Integer); + assertEquals((int) result0, value); + assertTrue(result1 instanceof Integer); + assertEquals((int) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedInt(int value) { + int result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Integer); + assertEquals((int) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedInt(int value) { + Object result0 = profile.profile((Object) value); + int result1 = profile.profile(value); + + assertTrue(result0 instanceof Integer); + assertEquals((int) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedLong(long value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Long); + assertEquals((long) result0, value); + assertTrue(result1 instanceof Long); + assertEquals((long) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedLong(long value) { + long result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Long); + assertEquals((long) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedLong(long value) { + Object result0 = profile.profile((Object) value); + long result1 = profile.profile(value); + + assertTrue(result0 instanceof Long); + assertEquals((long) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedFloat(float value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); + assertTrue(result1 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedFloat(float value) { + float result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); + assertTrue(result1 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedFloat(float value) { + Object result0 = profile.profile((Object) value); + float result1 = profile.profile(value); + + assertTrue(result0 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); + assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedDouble(double value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); + assertTrue(result1 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedDouble(double value) { + double result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); + assertTrue(result1 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedDouble(double value) { + Object result0 = profile.profile((Object) value); + double result1 = profile.profile(value); + + assertTrue(result0 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); + assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedBoolean(boolean value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Boolean); + assertEquals((boolean) result0, value); + assertTrue(result1 instanceof Boolean); + assertEquals((boolean) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedBoolean(boolean value) { + boolean result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Boolean); + assertEquals((boolean) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedBoolean(boolean value) { + Object result0 = profile.profile((Object) value); + boolean result1 = profile.profile(value); + + assertTrue(result0 instanceof Boolean); + assertEquals((boolean) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedChar(char value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Character); + assertEquals((char) result0, value); + assertTrue(result1 instanceof Character); + assertEquals((char) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedChar(char value) { + char result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Character); + assertEquals((char) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedCharacter(char value) { + Object result0 = profile.profile((Object) value); + char result1 = profile.profile(value); + + assertTrue(result0 instanceof Character); + assertEquals((char) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithByteThenObject(byte value0, Object value1) { + byte result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithShortThenObject(short value0, Object value1) { + short result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithIntThenObject(int value0, Object value1) { + int result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithLongThenObject(long value0, Object value1) { + long result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithFloatThenObject(float value0, Object value1) { + float result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithDoubleThenObject(double value0, Object value1) { + double result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithBooleanThenObject(boolean value0, Object value1) { + boolean result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithCharThenObject(char value0, Object value1) { + char result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Test + public void testNegativeZeroFloat() { + profile.profile(-0.0f); + profile.profile(+0.0f); + assertThat(profile.isGeneric(), is(true)); + } + + @Test + public void testNegativeZeroDouble() { + profile.profile(-0.0); + profile.profile(+0.0); + assertThat(profile.isGeneric(), is(true)); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/UnionAssumptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/UnionAssumptionTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013, 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.utilities; + +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.nodes.InvalidAssumptionException; +import com.oracle.truffle.api.utilities.UnionAssumption; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class UnionAssumptionTest { + + @Test + public void testIsValid() { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + assertTrue(union.isValid()); + } + + @Test + public void testCheck() throws InvalidAssumptionException { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + union.check(); + } + + @Test + public void testFirstInvalidateIsValid() { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + first.invalidate(); + + assertFalse(union.isValid()); + } + + @Test(expected = InvalidAssumptionException.class) + public void testFirstInvalidateCheck() throws InvalidAssumptionException { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + first.invalidate(); + + union.check(); + } + + @Test + public void testSecondInvalidateIsValid() { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + second.invalidate(); + + assertFalse(union.isValid()); + } + + @Test(expected = InvalidAssumptionException.class) + public void testSecondInvalidateCheck() throws InvalidAssumptionException { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + second.invalidate(); + + union.check(); + } + + @Test + public void testBothInvalidateIsValid() { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + first.invalidate(); + second.invalidate(); + + assertFalse(union.isValid()); + } + + @Test(expected = InvalidAssumptionException.class) + public void testBothInvalidateCheck() throws InvalidAssumptionException { + final Assumption first = Truffle.getRuntime().createAssumption("first"); + final Assumption second = Truffle.getRuntime().createAssumption("second"); + final UnionAssumption union = new UnionAssumption(first, second); + + first.invalidate(); + second.invalidate(); + + union.check(); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/AccessorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/AccessorTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.impl.Accessor; +import com.oracle.truffle.api.source.Source; + +import static com.oracle.truffle.api.vm.ImplicitExplicitExportTest.L1; + +import com.oracle.truffle.api.vm.PolyglotEngine; +import com.oracle.truffle.api.vm.ImplicitExplicitExportTest.ExportImportLanguage1; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class AccessorTest { + public static Accessor API; + + @BeforeClass + public static void initAccessors() throws Exception { + Field f = Accessor.class.getDeclaredField("API"); + f.setAccessible(true); + API = (Accessor) f.get(null); + } + + @Test + public void canGetAccessToOwnLanguageInstance() throws Exception { + PolyglotEngine vm = PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()).build(); + PolyglotEngine.Language language = vm.getLanguages().get(L1); + assertNotNull("L1 language is defined", language); + + Source s = Source.fromText("return nothing", "nothing"); + Object ret = language.eval(s).get(); + assertNull("nothing is returned", ret); + + Object afterInitialization = findLanguageByClass(vm); + assertNotNull("Language found", afterInitialization); + assertTrue("Right instance: " + afterInitialization, afterInitialization instanceof ExportImportLanguage1); + } + + Object findLanguageByClass(PolyglotEngine vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { + Method find = Accessor.class.getDeclaredMethod("findLanguage", Object.class, Class.class); + find.setAccessible(true); + TruffleLanguage.Env env = (TruffleLanguage.Env) find.invoke(API, vm, ExportImportLanguage1.class); + Field f = env.getClass().getDeclaredField("langCtx"); + f.setAccessible(true); + Object langCtx = f.get(env); + f = langCtx.getClass().getDeclaredField("lang"); + f.setAccessible(true); + return f.get(langCtx); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ArrayTruffleObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ArrayTruffleObject.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012, 2015, 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.vm; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.RootNode; +import java.util.List; +import static org.junit.Assert.assertNotEquals; + +final class ArrayTruffleObject implements TruffleObject, ForeignAccess.Factory10 { + private final ForeignAccess access; + private final Object[] values; + private final Thread forbiddenDupl; + + ArrayTruffleObject(Object[] values) { + this(values, null); + } + + ArrayTruffleObject(Object[] values, Thread forbiddenDupl) { + this.access = forbiddenDupl == null ? ForeignAccess.create(getClass(), this) : null; + this.values = values; + this.forbiddenDupl = forbiddenDupl; + } + + @Override + public ForeignAccess getForeignAccess() { + return access != null ? access : ForeignAccess.create(getClass(), this); + } + + @Override + public CallTarget accessIsNull() { + return target(RootNode.createConstantNode(Boolean.FALSE)); + } + + @Override + public CallTarget accessIsExecutable() { + return target(RootNode.createConstantNode(Boolean.FALSE)); + } + + @Override + public CallTarget accessIsBoxed() { + return target(RootNode.createConstantNode(Boolean.FALSE)); + } + + @Override + public CallTarget accessHasSize() { + return target(RootNode.createConstantNode(Boolean.TRUE)); + } + + @Override + public CallTarget accessGetSize() { + return target(RootNode.createConstantNode(values.length)); + } + + @Override + public CallTarget accessUnbox() { + return null; + } + + @Override + public CallTarget accessRead() { + return target(new IndexNode()); + } + + @Override + public CallTarget accessWrite() { + return null; + } + + @Override + public CallTarget accessExecute(int argumentsLength) { + return null; + } + + @Override + public CallTarget accessInvoke(int argumentsLength) { + if (argumentsLength == 0) { + return target(new DuplNode()); + } + if (argumentsLength == 1) { + return target(new InvokeNode()); + } + return null; + } + + @Override + public CallTarget accessNew(int argumentsLength) { + return null; + } + + @Override + public CallTarget accessMessage(Message unknown) { + return null; + } + + private static CallTarget target(RootNode node) { + return Truffle.getRuntime().createCallTarget(node); + } + + private final class IndexNode extends RootNode { + public IndexNode() { + super(TruffleLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + int index = ((Number) ForeignAccess.getArguments(frame).get(0)).intValue(); + if (values[index] instanceof Object[]) { + return new ArrayTruffleObject((Object[]) values[index]); + } else { + return values[index]; + } + } + } + + private final class InvokeNode extends RootNode { + public InvokeNode() { + super(TruffleLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + final List args = ForeignAccess.getArguments(frame); + if (!"get".equals(args.get(0))) { + return null; + } + int index = ((Number) args.get(1)).intValue(); + if (values[index] instanceof Object[]) { + return new ArrayTruffleObject((Object[]) values[index]); + } else { + return values[index]; + } + } + } + + private final class DuplNode extends RootNode { + public DuplNode() { + super(TruffleLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + final List args = ForeignAccess.getArguments(frame); + if (!"dupl".equals(args.get(0))) { + return null; + } + assertNotEquals("Cannot allocate duplicate on forbidden thread", forbiddenDupl, Thread.currentThread()); + return new ArrayTruffleObject(values); + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineAsynchTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineAsynchTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 2015, 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.vm; + +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.util.concurrent.Executors; +import org.junit.Test; + +public class EngineAsynchTest extends EngineTest { + @Test + public void marker() { + } + + @Override + protected Thread forbiddenThread() { + return Thread.currentThread(); + } + + @Override + protected PolyglotEngine.Builder createBuilder() { + return PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineSingleThreadedTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineSingleThreadedTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012, 2015, 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.vm; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import org.junit.Before; +import org.junit.Test; + +public class EngineSingleThreadedTest { + PolyglotEngine tvm; + + @Before + public void initInDifferentThread() throws InterruptedException { + final PolyglotEngine.Builder b = PolyglotEngine.newBuilder(); + Thread t = new Thread("Initializer") { + @Override + public void run() { + tvm = b.build(); + } + }; + t.start(); + t.join(); + } + + @Test(expected = IllegalStateException.class) + public void evalURI() throws IOException { + tvm.eval(Source.fromURL(new File(".").toURI().toURL(), "wrong.test")); + } + + @Test(expected = IllegalStateException.class) + public void evalString() throws IOException { + tvm.eval(Source.fromText("1 + 1", "wrong.test").withMimeType("text/javascript")); + } + + @Test(expected = IllegalStateException.class) + public void evalReader() throws IOException { + try (StringReader sr = new StringReader("1 + 1")) { + tvm.eval(Source.fromReader(sr, "wrong.test").withMimeType("text/javascript")); + } + } + + @Test(expected = IllegalStateException.class) + public void evalSource() throws IOException { + tvm.eval(Source.fromText("", "Empty")); + } + + @Test(expected = IllegalStateException.class) + public void findGlobalSymbol() { + tvm.findGlobalSymbol("doesNotExists"); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/EngineTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, 2015, 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.vm; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.io.IOException; +import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +public class EngineTest { + protected PolyglotEngine.Builder createBuilder() { + return PolyglotEngine.newBuilder(); + } + + @Test + public void npeWhenCastingAs() throws Exception { + PolyglotEngine tvm = createBuilder().build(); + + PolyglotEngine.Language language1 = tvm.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = tvm.getLanguages().get("application/x-test-import-export-2"); + language2.eval(Source.fromText("explicit.value=42", "define 42")); + + PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); + String res = value.as(String.class); + assertNotNull(res); + } + + @Test + public void checkCachingOfNodes() throws IOException { + PolyglotEngine vm1 = createBuilder().build(); + PolyglotEngine vm2 = createBuilder().build(); + + PolyglotEngine.Language language1 = vm1.getLanguages().get("application/x-test-hash"); + PolyglotEngine.Language language2 = vm2.getLanguages().get("application/x-test-hash"); + PolyglotEngine.Language alt1 = vm1.getLanguages().get("application/x-test-hash-alt"); + PolyglotEngine.Language alt2 = vm2.getLanguages().get("application/x-test-hash-alt"); + final Source sharedSource = Source.fromText("anything", "something"); + + Object hashIn1Round1 = language1.eval(sharedSource).get(); + Object hashIn2Round1 = language2.eval(sharedSource).get(); + Object hashIn1Round2 = language1.eval(sharedSource).get(); + Object hashIn2Round2 = language2.eval(sharedSource).get(); + + Object altIn1Round1 = alt1.eval(sharedSource).get(); + Object altIn2Round1 = alt2.eval(sharedSource).get(); + Object altIn1Round2 = alt1.eval(sharedSource).get(); + Object altIn2Round2 = alt2.eval(sharedSource).get(); + + assertEquals("Two executions in 1st engine share the nodes", hashIn1Round1, hashIn1Round2); + assertEquals("Two executions in 2nd engine share the nodes", hashIn2Round1, hashIn2Round2); + + assertEquals("Two alternative executions in 1st engine share the nodes", altIn1Round1, altIn1Round2); + assertEquals("Two alternative executions in 2nd engine share the nodes", altIn2Round1, altIn2Round2); + + assertNotEquals("Two executions in different languages don't share the nodes", hashIn1Round1, altIn1Round1); + assertNotEquals("Two executions in different languages don't share the nodes", hashIn1Round1, altIn2Round1); + assertNotEquals("Two executions in different languages don't share the nodes", hashIn2Round2, altIn1Round2); + assertNotEquals("Two executions in different languages don't share the nodes", hashIn2Round2, altIn2Round2); + + assertNotEquals("Two executions in different engines don't share the nodes", hashIn1Round1, hashIn2Round1); + assertNotEquals("Two executions in different engines don't share the nodes", hashIn2Round2, hashIn1Round2); + } + + protected Thread forbiddenThread() { + return null; + } + + private interface AccessArray { + AccessArray dupl(); + + List get(int index); + } + + @Test + public void wrappedAsArray() throws Exception { + Object[][] matrix = {{1, 2, 3}}; + + PolyglotEngine tvm = createBuilder().globalSymbol("arr", new ArrayTruffleObject(matrix, forbiddenThread())).build(); + PolyglotEngine.Language language1 = tvm.getLanguages().get("application/x-test-import-export-1"); + AccessArray access = language1.eval(Source.fromText("return=arr", "get the array")).as(AccessArray.class); + assertNotNull("Array converted to list", access); + access = access.dupl(); + List list = access.get(0); + assertEquals("Size 3", 3, list.size()); + assertEquals(1, list.get(0)); + assertEquals(2, list.get(1)); + assertEquals(3, list.get(2)); + Integer[] arr = list.toArray(new Integer[0]); + assertEquals("Three items in array", 3, arr.length); + assertEquals(1, arr[0].intValue()); + assertEquals(2, arr[1].intValue()); + assertEquals(3, arr[2].intValue()); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ExceptionDuringParsingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ExceptionDuringParsingTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import com.oracle.truffle.api.impl.Accessor; +import com.oracle.truffle.api.source.Source; + +import static com.oracle.truffle.api.vm.ImplicitExplicitExportTest.L1; + +import com.oracle.truffle.api.vm.PolyglotEngine; +import com.oracle.truffle.api.vm.ImplicitExplicitExportTest.Ctx; + +import java.io.IOException; + +import org.junit.After; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; + +public class ExceptionDuringParsingTest { + public static Accessor API; + + @Before + @After + public void cleanTheSet() { + Ctx.disposed.clear(); + } + + @Test + public void canGetAccessToOwnLanguageInstance() throws Exception { + PolyglotEngine vm = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Language language = vm.getLanguages().get(L1); + assertNotNull("L1 language is defined", language); + + final Source src = Source.fromText("parse=No, no, no!", "Fail on parsing").withMimeType(L1); + try { + vm.eval(src); + fail("Exception thrown"); + } catch (IOException ex) { + assertEquals(ex.getMessage(), "No, no, no!"); + } + + assertEquals("No dispose yet", 0, Ctx.disposed.size()); + + vm.dispose(); + + assertEquals("One context disposed", 1, Ctx.disposed.size()); + + try { + vm.eval(src); + fail("Should throw an exception"); + } catch (IllegalStateException ex) { + assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); + } + try { + vm.findGlobalSymbol("nothing"); + fail("Should throw an exception"); + } catch (IllegalStateException ex) { + assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); + } + try { + vm.dispose(); + fail("Should throw an exception"); + } catch (IllegalStateException ex) { + assertTrue(ex.getMessage(), ex.getMessage().contains("disposed")); + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/GlobalSymbolAsynchTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/GlobalSymbolAsynchTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import com.oracle.truffle.api.vm.PolyglotEngine; + +import java.util.concurrent.Executors; + +import org.junit.Test; + +public class GlobalSymbolAsynchTest extends GlobalSymbolTest { + @Test + public void marker() { + } + + @Override + protected PolyglotEngine.Builder createEngineBuilder() { + return PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/GlobalSymbolTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/GlobalSymbolTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.utilities.InstrumentationTestMode; + +import static com.oracle.truffle.api.vm.ImplicitExplicitExportTest.L3; + +import com.oracle.truffle.api.vm.PolyglotEngine; + +import java.io.IOException; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GlobalSymbolTest { + + @Before + public void before() { + InstrumentationTestMode.set(true); + } + + @After + public void after() { + InstrumentationTestMode.set(false); + } + + @Test + public void globalSymbolFoundByLanguage() throws IOException { + PolyglotEngine vm = createEngineBuilder().globalSymbol("ahoj", "42").build(); + // @formatter:off + Object ret = vm.eval( + Source.fromText("return=ahoj", "Return").withMimeType(L3) + ).get(); + // @formatter:on + assertEquals("42", ret); + } + + @Test + public void globalSymbolFoundByVMUser() throws IOException { + PolyglotEngine vm = createEngineBuilder().globalSymbol("ahoj", "42").build(); + PolyglotEngine.Value ret = vm.findGlobalSymbol("ahoj"); + assertNotNull("Symbol found", ret); + assertEquals("42", ret.get()); + } + + protected PolyglotEngine.Builder createEngineBuilder() { + return PolyglotEngine.newBuilder(); + } + + @Test + public void passingArray() throws IOException { + PolyglotEngine vm = createEngineBuilder().globalSymbol("arguments", new Object[]{"one", "two", "three"}).build(); + PolyglotEngine.Value value = vm.findGlobalSymbol("arguments"); + assertFalse("Not instance of array", value.get() instanceof Object[]); + assertTrue("Instance of TruffleObject", value.get() instanceof TruffleObject); + List args = value.as(List.class); + assertNotNull("Can be converted to List", args); + assertEquals("Three items", 3, args.size()); + assertEquals("one", args.get(0)); + assertEquals("two", args.get(1)); + assertEquals("three", args.get(2)); + String[] arr = args.toArray(new String[0]); + assertEquals("Three items in array", 3, arr.length); + assertEquals("one", arr[0]); + assertEquals("two", arr[1]); + assertEquals("three", arr[2]); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/HashLanguage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/HashLanguage.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.TruffleLanguage.Env; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import java.io.IOException; + +@TruffleLanguage.Registration(name = "Hash", mimeType = "application/x-test-hash", version = "1.0") +public class HashLanguage extends TruffleLanguage { + public static final HashLanguage INSTANCE = new HashLanguage(); + + @Override + protected Env createContext(Env env) { + return env; + } + + @Override + protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { + return Truffle.getRuntime().createCallTarget(new HashNode(this, code)); + } + + @Override + protected Object findExportedSymbol(Env context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Env context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected boolean isInstrumentable(Node node) { + return false; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + throw new UnsupportedOperationException(); + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of + // generated methods, choose + // Tools | Templates. + } + + private static class HashNode extends RootNode { + private static int counter; + private final Source code; + private final int id; + + public HashNode(HashLanguage hash, Source code) { + super(hash.getClass(), null, null); + this.code = code; + id = ++counter; + } + + @Override + public Object execute(VirtualFrame frame) { + return System.identityHashCode(this) + "@" + code.getCode() + " @ " + id; + } + } + + @TruffleLanguage.Registration(name = "AltHash", mimeType = "application/x-test-hash-alt", version = "1.0") + public static final class SubLang extends HashLanguage { + public static final SubLang INSTANCE = new SubLang(); + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ImplicitExplicitExportTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ImplicitExplicitExportTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2015, 2015, 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.vm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.Reader; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.Executors; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.TruffleLanguage.Env; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.util.Objects; + +public class ImplicitExplicitExportTest { + private static Thread mainThread; + private PolyglotEngine vm; + + @Before + public void initializeVM() { + mainThread = Thread.currentThread(); + vm = PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor()).build(); + assertTrue("Found " + L1 + " language", vm.getLanguages().containsKey(L1)); + assertTrue("Found " + L2 + " language", vm.getLanguages().containsKey(L2)); + assertTrue("Found " + L3 + " language", vm.getLanguages().containsKey(L3)); + } + + @After + public void cleanThread() { + mainThread = null; + } + + @Test + public void explicitExportFound() throws IOException { + // @formatter:off + vm.eval(Source.fromText("explicit.ahoj=42", "Fourty two").withMimeType(L1)); + Object ret = vm.eval( + Source.fromText("return=ahoj", "Return").withMimeType(L3) + ).get(); + // @formatter:on + assertEquals("42", ret); + } + + @Test + public void implicitExportFound() throws IOException { + // @formatter:off + vm.eval( + Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L1) + ); + Object ret = vm.eval( + Source.fromText("return=ahoj", "Return").withMimeType(L3) + ).get(); + // @formatter:on + assertEquals("42", ret); + } + + @Test + public void explicitExportPreferred2() throws IOException { + // @formatter:off + vm.eval( + Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L1) + ); + vm.eval( + Source.fromText("explicit.ahoj=43", "Fourty three").withMimeType(L2) + ); + Object ret = vm.eval( + Source.fromText("return=ahoj", "Return").withMimeType(L3) + ).get(); + // @formatter:on + assertEquals("Explicit import from L2 is used", "43", ret); + assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").get()); + } + + @Test + public void explicitExportPreferred1() throws IOException { + // @formatter:off + vm.eval( + Source.fromText("explicit.ahoj=43", "Fourty three").withMimeType(L1) + ); + vm.eval( + Source.fromText("implicit.ahoj=42", "Fourty two").withMimeType(L2) + ); + Object ret = vm.eval( + Source.fromText("return=ahoj", "Return").withMimeType(L3) + ).get(); + // @formatter:on + assertEquals("Explicit import from L2 is used", "43", ret); + assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").invoke(null).get()); + } + + static final class Ctx { + static final Set disposed = new HashSet<>(); + + final Map explicit = new HashMap<>(); + final Map implicit = new HashMap<>(); + final Env env; + + public Ctx(Env env) { + this.env = env; + } + + void dispose() { + disposed.add(this); + } + } + + private abstract static class AbstractExportImportLanguage extends TruffleLanguage { + + @Override + protected Ctx createContext(Env env) { + if (mainThread != null) { + assertNotEquals("Should run asynchronously", Thread.currentThread(), mainThread); + } + return new Ctx(env); + } + + @Override + protected void disposeContext(Ctx context) { + context.dispose(); + } + + @Override + protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { + if (code.getCode().startsWith("parse=")) { + throw new IOException(code.getCode().substring(6)); + } + return new ValueCallTarget(code, this); + } + + @Override + protected Object findExportedSymbol(Ctx context, String globalName, boolean onlyExplicit) { + if (context.explicit.containsKey(globalName)) { + return context.explicit.get(globalName); + } + if (!onlyExplicit && context.implicit.containsKey(globalName)) { + return context.implicit.get(globalName); + } + return null; + } + + @Override + protected Object getLanguageGlobal(Ctx context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected boolean isInstrumentable(Node node) { + return false; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + return null; + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + return null; + } + + private Object importExport(Source code) { + assertNotEquals("Should run asynchronously", Thread.currentThread(), mainThread); + final Node node = createFindContextNode(); + Ctx ctx = findContext(node); + Properties p = new Properties(); + try (Reader r = code.getReader()) { + p.load(r); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + Enumeration en = p.keys(); + while (en.hasMoreElements()) { + Object n = en.nextElement(); + if (n instanceof String) { + String k = (String) n; + if (k.startsWith("explicit.")) { + ctx.explicit.put(k.substring(9), p.getProperty(k)); + } + if (k.startsWith("implicit.")) { + ctx.implicit.put(k.substring(9), p.getProperty(k)); + } + if (k.equals("return")) { + return ctx.env.importSymbol(p.getProperty(k)); + } + } + } + return null; + } + } + + private static final class ValueCallTarget implements RootCallTarget { + private final Source code; + private final AbstractExportImportLanguage language; + + private ValueCallTarget(Source code, AbstractExportImportLanguage language) { + this.code = code; + this.language = language; + } + + @Override + public RootNode getRootNode() { + throw new UnsupportedOperationException(); + } + + @Override + public Object call(Object... arguments) { + return language.importExport(code); + } + } + + static final String L1 = "application/x-test-import-export-1"; + static final String L2 = "application/x-test-import-export-2"; + static final String L3 = "application/x-test-import-export-3"; + + @TruffleLanguage.Registration(mimeType = L1, name = "ImportExport1", version = "0") + public static final class ExportImportLanguage1 extends AbstractExportImportLanguage { + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage1(); + + public ExportImportLanguage1() { + } + + @Override + protected String toString(Ctx ctx, Object value) { + if (value instanceof String) { + try { + int number = Integer.parseInt((String) value); + return number + ": Int"; + } catch (NumberFormatException ex) { + // go on + } + } + return Objects.toString(value); + } + } + + @TruffleLanguage.Registration(mimeType = L2, name = "ImportExport2", version = "0") + public static final class ExportImportLanguage2 extends AbstractExportImportLanguage { + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage2(); + + public ExportImportLanguage2() { + } + + @Override + protected String toString(Ctx ctx, Object value) { + if (value instanceof String) { + try { + double number = Double.parseDouble((String) value); + return number + ": Double"; + } catch (NumberFormatException ex) { + // go on + } + } + return Objects.toString(value); + } + } + + @TruffleLanguage.Registration(mimeType = L3, name = "ImportExport3", version = "0") + public static final class ExportImportLanguage3 extends AbstractExportImportLanguage { + public static final AbstractExportImportLanguage INSTANCE = new ExportImportLanguage3(); + + private ExportImportLanguage3() { + } + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/InitializationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/InitializationTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2014, 2015, 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.vm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.Test; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.TruffleLanguage.Env; +import com.oracle.truffle.api.debug.Breakpoint; +import com.oracle.truffle.api.debug.Debugger; +import com.oracle.truffle.api.debug.ExecutionEvent; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.ASTProber; +import com.oracle.truffle.api.instrument.EventHandlerNode; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.StandardSyntaxTag; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeVisitor; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.vm.EventConsumer; +import com.oracle.truffle.api.vm.PolyglotEngine; + +/** + * Bug report validating test. + *

+ * It has been reported that calling {@link Env#importSymbol(java.lang.String)} in + * {@link TruffleLanguage TruffleLanguage.createContext(env)} yields a {@link NullPointerException}. + *

+ * The other report was related to specifying an abstract language class in the RootNode and + * problems with debugging later on. That is what the other part of this test - once it obtains + * Debugger instance simulates. + */ +public class InitializationTest { + + @Test + public void accessProbeForAbstractLanguage() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + final Debugger[] arr = {null}; + PolyglotEngine vm = PolyglotEngine.newBuilder().onEvent(new EventConsumer(ExecutionEvent.class) { + @Override + protected void on(ExecutionEvent event) { + arr[0] = event.getDebugger(); + } + }).build(); + + final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + instrumenter.registerASTProber(new ASTProber() { + + public void probeAST(final Instrumenter inst, RootNode startNode) { + startNode.accept(new NodeVisitor() { + + public boolean visit(Node node) { + + if (node instanceof ANode) { + inst.probe(node).tagAs(StandardSyntaxTag.STATEMENT, null); + } + return true; + } + }); + } + }); + + Source source = Source.fromText("accessProbeForAbstractLanguage text", "accessProbeForAbstractLanguage").withMimeType("application/x-abstrlang"); + + assertEquals(vm.eval(source).get(), 1); + + assertNotNull("Debugger found", arr[0]); + + Debugger d = arr[0]; + Breakpoint b = d.setLineBreakpoint(0, source.createLineLocation(1), true); + assertTrue(b.isEnabled()); + b.setCondition("true"); + + assertEquals(vm.eval(source).get(), 1); + vm.dispose(); + } + + private static final class MMRootNode extends RootNode { + @Child ANode node; + + MMRootNode(SourceSection ss) { + super(AbstractLanguage.class, ss, null); + node = new ANode(42); + adoptChildren(); + } + + @Override + public Object execute(VirtualFrame frame) { + return node.constant(); + } + } + + private static class ANode extends Node { + private final int constant; + + public ANode(int constant) { + this.constant = constant; + } + + @Override + public SourceSection getSourceSection() { + return getRootNode().getSourceSection(); + } + + Object constant() { + return constant; + } + } + + private static class ANodeWrapper extends ANode implements WrapperNode { + @Child ANode child; + @Child private EventHandlerNode eventHandlerNode; + + ANodeWrapper(ANode node) { + super(1); // dummy + this.child = node; + } + + @Override + public Node getChild() { + return child; + } + + @Override + public Probe getProbe() { + return eventHandlerNode.getProbe(); + } + + @Override + public void insertEventHandlerNode(EventHandlerNode eventHandler) { + this.eventHandlerNode = eventHandler; + } + + @Override + public String instrumentationInfo() { + throw new UnsupportedOperationException(); + } + } + + private abstract static class AbstractLanguage extends TruffleLanguage { + } + + @TruffleLanguage.Registration(mimeType = "application/x-abstrlang", name = "AbstrLang", version = "0.1") + public static final class TestLanguage extends AbstractLanguage { + public static final TestLanguage INSTANCE = new TestLanguage(); + + @Override + protected Object createContext(Env env) { + assertNull("Not defined symbol", env.importSymbol("unknown")); + return env; + } + + @Override + protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { + return Truffle.getRuntime().createCallTarget(new MMRootNode(code.createSection("1st line", 1))); + } + + @Override + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Object context) { + throw new UnsupportedOperationException(); + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public Object evalInContext(Source source, Node node, MaterializedFrame mFrame) { + throw new UnsupportedOperationException(); + } + + @Override + public Visualizer getVisualizer() { + throw new UnsupportedOperationException(); + } + + @Override + protected boolean isInstrumentable(Node node) { + return node instanceof ANode; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + return node instanceof ANode ? new ANodeWrapper((ANode) node) : null; + } + } +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ToStringTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ToStringTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 2015, 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.vm; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class ToStringTest { + @Test + public void valueToStringValueWith1() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language2.eval(Source.fromText("explicit.value=42", "define 42")); + PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); + assertEquals("It's fourtytwo", "42", value.get()); + + String textual = value.as(String.class); + assertEquals("Nicely formated as by L1", "42: Int", textual); + } + + @Test + public void valueToStringValueWith2() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language1.eval(Source.fromText("explicit.value=42", "define 42")); + PolyglotEngine.Value value = language2.eval(Source.fromText("return=value", "42.value")); + assertEquals("It's fourtytwo", "42", value.get()); + + String textual = value.as(String.class); + assertEquals("Nicely formated as by L2", "42.0: Double", textual); + } + +} diff -r 70a10a9f28ad -r fec62e298245 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ValueTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/vm/ValueTest.java Wed Dec 02 15:16:27 2015 +0100 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, 2015, 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.vm; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.Test; + +public class ValueTest implements Executor { + private List pending = new LinkedList<>(); + + @Test + public void valueToStringValue() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language2.eval(Source.fromText("explicit.value=42", "define 42")); + PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); + assertEquals("It's fourtytwo", "42", value.get()); + + String textual = value.toString(); + assertTrue("Contains the value " + textual, textual.contains("value=42")); + assertTrue("Is computed " + textual, textual.contains("computed=true")); + assertTrue("No error " + textual, textual.contains("exception=null")); + } + + @Test + public void valueToStringException() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Value value = null; + try { + value = language1.eval(Source.fromText("parse=does not work", "error.value")); + Object res = value.get(); + fail("Should throw an exception: " + res); + } catch (IOException ex) { + assertTrue("Message contains the right text: " + ex.getMessage(), ex.getMessage().contains("does not work")); + } + + assertNull("No value returned", value); + } + + @Test + public void valueToStringValueAsync() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().executor(this).build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language2.eval(Source.fromText("explicit.value=42", "define 42")); + flush(); + + PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); + + String textual = value.toString(); + assertFalse("Doesn't contain the value " + textual, textual.contains("value=42")); + assertTrue("Is not computed " + textual, textual.contains("computed=false")); + assertTrue("No error " + textual, textual.contains("exception=null")); + assertTrue("No value yet " + textual, textual.contains("value=null")); + + flush(); + + textual = value.toString(); + assertTrue("Is computed " + textual, textual.contains("computed=true")); + assertTrue("No error " + textual, textual.contains("exception=null")); + assertTrue("value computed " + textual, textual.contains("value=42")); + } + + @Test + public void valueToStringExceptionAsync() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().executor(this).build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Value value = language1.eval(Source.fromText("parse=does not work", "error.value")); + assertNotNull("Value returned", value); + + String textual = value.toString(); + assertTrue("Is not computed " + textual, textual.contains("computed=false")); + assertTrue("No error " + textual, textual.contains("exception=null")); + assertTrue("No value yet " + textual, textual.contains("value=null")); + + flush(); + + textual = value.toString(); + assertTrue("Is computed " + textual, textual.contains("computed=true")); + assertTrue("No value at all" + textual, textual.contains("value=null")); + assertTrue("Error " + textual, textual.contains("exception=java.io.IOException: does not work")); + } + + @Override + public void execute(Runnable command) { + pending.add(command); + } + + private void flush() { + for (Runnable r : pending) { + r.run(); + } + } +}