# HG changeset patch # User Jaroslav Tulach # Date 1434531488 -7200 # Node ID 9c8c0937da413d1bbadcec6ea5d640599a3bf3f0 # Parent 2a5011c7e6417ce5e5113d2f51d66e1ebce18a64 Moving all sources into truffle subdirectory diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ArrayTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ArrayTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +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.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ArrayTestFactory.TestNode1NodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public class ArrayTest { - - @Test - public void testNode1() { - final TestNode1 node = TestNode1NodeGen.create(null); - RootNode root = new RootNode() { - @Child TestNode1 test = node; - - @Override - public Object execute(VirtualFrame frame) { - return test.executeWith(frame, frame.getArguments()[0]); - } - }; - CallTarget target = Truffle.getRuntime().createCallTarget(root); - - Assert.assertEquals(1, (int) target.call(1)); - Assert.assertArrayEquals(new double[0], (double[]) target.call(new int[0]), 0.0d); - Assert.assertArrayEquals(new double[0], (double[]) target.call(new double[0]), 0.0d); - Assert.assertArrayEquals(new String[0], (String[]) target.call((Object) new String[0])); - } - - @TypeSystemReference(ArrayTypeSystem.class) - abstract static class BaseNode extends Node { - - abstract Object execute(VirtualFrame frame); - - int executeInt(VirtualFrame frame) throws UnexpectedResultException { - return ArrayTypeSystemGen.expectInteger(execute(frame)); - } - - int[] executeIntArray(VirtualFrame frame) throws UnexpectedResultException { - return ArrayTypeSystemGen.expectIntArray(execute(frame)); - } - - String[] executeStringArray(VirtualFrame frame) throws UnexpectedResultException { - return ArrayTypeSystemGen.expectStringArray(execute(frame)); - } - - double[] executeDoubleArray(VirtualFrame frame) throws UnexpectedResultException { - return ArrayTypeSystemGen.expectDoubleArray(execute(frame)); - } - } - - @NodeChild - abstract static class TestNode1 extends BaseNode { - - abstract Object executeWith(VirtualFrame frame, Object operand); - - @Specialization - int doInt(int value) { - return value; - } - - @Specialization - double[] doDoubleArray(double[] value) { - return value; - } - - @Specialization - String[] doStringArray(String[] value) { - return value; - } - - } - - @TypeSystem({int.class, int[].class, double[].class, String[].class, Object[].class}) - public static class ArrayTypeSystem { - - @ImplicitCast - public static double[] castFromInt(int[] array) { - double[] newArray = new double[array.length]; - for (int i = 0; i < array.length; i++) { - newArray[i] = array[i]; - } - return newArray; - } - - @TypeCheck(int[].class) - public static boolean isIntArray2(Object array) { - return array instanceof int[]; - } - - @TypeCast(int[].class) - public static int[] asIntArray(Object array) { - return (int[]) array; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.AssumptionArrayTestFactory; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.CacheAssumptionTestFactory; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.FieldTestFactory; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.MethodTestFactory; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.NodeFieldTest2Factory; -import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.StaticFieldTestFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class AssumptionsTest { - - @Test - public void testField() { - CallTarget root = createCallTarget(FieldTestFactory.getInstance()); - FieldTest node = getNode(root); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(42)); - node.field.invalidate(); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class FieldTest extends ValueNode { - - protected final Assumption field = Truffle.getRuntime().createAssumption(); - - @Specialization(assumptions = "field") - static int do1(int value) { - return value; - } - } - - @Test - public void testNodeField() { - Assumption assumption = Truffle.getRuntime().createAssumption(); - CallTarget root = createCallTarget(NodeFieldTest2Factory.getInstance(), assumption); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(42)); - assumption.invalidate(); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - @NodeField(name = "field", type = Assumption.class) - static class NodeFieldTest2 extends ValueNode { - - @Specialization(assumptions = "field") - static int do1(int value) { - return value; - } - } - - @Test - public void testStaticField() { - CallTarget root = createCallTarget(StaticFieldTestFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(42)); - StaticFieldTest.FIELD.invalidate(); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class StaticFieldTest extends ValueNode { - - static final Assumption FIELD = Truffle.getRuntime().createAssumption(); - - @Specialization(assumptions = "FIELD") - static int do1(int value) { - return value; - } - } - - @Test - public void testMethod() { - CallTarget root = createCallTarget(MethodTestFactory.getInstance()); - MethodTest node = getNode(root); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(42)); - node.hiddenAssumption.invalidate(); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class MethodTest extends ValueNode { - - private final Assumption hiddenAssumption = Truffle.getRuntime().createAssumption(); - - @Specialization(assumptions = "getAssumption()") - static int do1(int value) { - return value; - } - - Assumption getAssumption() { - return hiddenAssumption; - } - } - - @Test - public void testCacheAssumption() { - CallTarget root = createCallTarget(CacheAssumptionTestFactory.getInstance()); - CacheAssumptionTest node = getNode(root); - assertEquals("do1", root.call(42)); - assertEquals("do1", root.call(43)); - assertEquals("do1", root.call(44)); - node.assumptions.get(42).invalidate(); - node.assumptions.put(42, null); // clear 42 - node.assumptions.get(43).invalidate(); - node.assumptions.get(44).invalidate(); - assertEquals("do1", root.call(42)); // recreates 42 - assertEquals("do2", root.call(43)); // invalid 43 -> remove -> insert do2 - assertEquals("do2", root.call(46)); // no more lines can be created. - } - - @Test - public void testCacheAssumptionLimit() { - CallTarget root = createCallTarget(CacheAssumptionTestFactory.getInstance()); - assertEquals("do1", root.call(42)); - assertEquals("do1", root.call(43)); - assertEquals("do1", root.call(44)); - assertEquals("do2", root.call(45)); - assertEquals("do1", root.call(43)); - assertEquals("do1", root.call(44)); - } - - @NodeChild - @SuppressWarnings("unused") - static class CacheAssumptionTest extends ValueNode { - - private final Map assumptions = new HashMap<>(); - - @Specialization(guards = "value == cachedValue", assumptions = "getAssumption(cachedValue)") - static String do1(int value, @Cached("value") int cachedValue) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - Assumption getAssumption(int value) { - Assumption assumption = assumptions.get(value); - if (assumption == null) { - assumption = Truffle.getRuntime().createAssumption(); - assumptions.put(value, assumption); - } - return assumption; - } - } - - @Test - public void testAssumptionArrays() { - CallTarget root = createCallTarget(AssumptionArrayTestFactory.getInstance()); - AssumptionArrayTest node = getNode(root); - - Assumption a1 = Truffle.getRuntime().createAssumption(); - Assumption a2 = Truffle.getRuntime().createAssumption(); - - node.assumptions = new Assumption[]{a1, a2}; - - assertEquals("do1", root.call(42)); - - a2.invalidate(); - - assertEquals("do2", root.call(42)); - } - - @NodeChild - @SuppressWarnings("unused") - static class AssumptionArrayTest extends ValueNode { - - Assumption[] assumptions; - - @Specialization(assumptions = "assumptions") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - } - - @NodeChild - static class ErrorIncompatibleReturnType extends ValueNode { - @ExpectError("Incompatible return type int. Assumptions must be assignable to Assumption or Assumption[].") - @Specialization(assumptions = "3") - static int do1(int value) { - return value; - } - } - - @NodeChild - static class ErrorBoundDynamicValue extends ValueNode { - - @ExpectError("Assumption expressions must not bind dynamic parameter values.") - @Specialization(assumptions = "createAssumption(value)") - static int do1(int value) { - return value; - } - - Assumption createAssumption(int value) { - return Truffle.getRuntime().createAssumption(String.valueOf(value)); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BadLongOverflowSpecializationTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BadLongOverflowSpecializationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.BadLongOverflowSpecializationTestFactory.ImplicitCastExclusionFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class BadLongOverflowSpecializationTest { - - /* Regression test for */ - - @NodeChild - @SuppressWarnings("unused") - abstract static class ImplicitCastExclusion extends ValueNode { - - @Specialization(rewriteOn = RuntimeException.class) - String f1(long a) { - return "triggered1"; - } - - @Specialization - String f2(long a) { - return "triggered2"; - } - } - - @Test - public void testAdd() { - TestRootNode node = createRoot(ImplicitCastExclusionFactory.getInstance()); - assertEquals("triggered1", executeWith(node, -1)); - assertEquals("triggered1", executeWith(node, 5000L)); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BinaryNodeTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BinaryNodeTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.BinaryNodeTestFactory.AddNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class BinaryNodeTest { - - @Test - public void testAdd() { - TestRootNode node = createRoot(AddNodeFactory.getInstance()); - assertEquals(42, executeWith(node, 19, 23)); - assertEquals(42d, executeWith(node, 19d, 23d)); - assertEquals(42d, executeWith(node, "19", "23")); - assertEquals(42, executeWith(node, 19, 23)); - } - - @Test(expected = RuntimeException.class) - public void testAddUnsupported() { - TestRootNode node = createRoot(AddNodeFactory.getInstance()); - executeWith(node, new Object(), new Object()); - } - - @NodeChildren({@NodeChild("left"), @NodeChild("right")}) - abstract static class BinaryNode extends ValueNode { - } - - abstract static class AddNode extends BinaryNode { - - @Specialization - int add(int left, int right) { - return left + right; - } - - @Fallback - Object add(Object left, Object right) { - return convertDouble(left) + convertDouble(right); - } - - static double convertDouble(Object value) { - if (value instanceof Number) { - return ((Number) value).doubleValue(); - } else if (value instanceof String) { - return Double.parseDouble((String) value); - } - throw new RuntimeException("Invalid datatype"); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BoxedString.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BoxedString.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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.dsl.test; - -public class BoxedString { - - private final String delegate; - - public BoxedString(String delegate) { - this.delegate = delegate; - } - - public String getDelegate() { - return delegate; - } - - @Override - public String toString() { - return getDelegate(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CachedTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CachedTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,340 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.BoundCacheFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.BoundCacheOverflowFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestBoundCacheOverflowContainsFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestCacheFieldFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestCacheMethodFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestCacheNodeFieldFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestGuardWithCachedAndDynamicParameterFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestGuardWithJustCachedParameterFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.TestMultipleCachesFactory; -import com.oracle.truffle.api.dsl.test.CachedTestFactory.UnboundCacheFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -@SuppressWarnings("unused") -public class CachedTest { - - @Test - public void testUnboundCache() { - CallTarget root = createCallTarget(UnboundCacheFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(43)); - assertEquals(42, root.call(44)); - } - - @NodeChild - static class UnboundCache extends ValueNode { - @Specialization - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - } - - @Test - public void testBoundCache() { - CallTarget root = createCallTarget(BoundCacheFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - assertEquals(44, root.call(44)); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class BoundCache extends ValueNode { - - @Specialization(guards = "value == cachedValue", limit = "3") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - } - - @Test - public void testBoundCacheOverflow() { - CallTarget root = createCallTarget(BoundCacheOverflowFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - assertEquals(-1, root.call(44)); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - assertEquals(-1, root.call(44)); - } - - @NodeChild - static class BoundCacheOverflow extends ValueNode { - - @Specialization(guards = "value == cachedValue", limit = "2") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - @Specialization - static int do2(int value) { - return -1; - } - - } - - @Test - public void testBoundCacheOverflowContains() { - CallTarget root = createCallTarget(TestBoundCacheOverflowContainsFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - assertEquals(-1, root.call(44)); - assertEquals(-1, root.call(42)); - assertEquals(-1, root.call(43)); - assertEquals(-1, root.call(44)); - } - - @NodeChild - static class TestBoundCacheOverflowContains extends ValueNode { - - @Specialization(guards = "value == cachedValue", limit = "2") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - @Specialization(contains = "do1") - static int do2(int value) { - return -1; - } - - } - - @Test - public void testCacheField() { - CallTarget root = createCallTarget(TestCacheFieldFactory.getInstance()); - assertEquals(3, root.call(42)); - assertEquals(3, root.call(43)); - } - - @NodeChild - static class TestCacheField extends ValueNode { - - protected int field = 3; - - @Specialization() - static int do1(int value, @Cached("field") int cachedValue) { - return cachedValue; - } - - } - - @Test - public void testCacheNodeField() { - CallTarget root = createCallTarget(TestCacheNodeFieldFactory.getInstance(), 21); - assertEquals(21, root.call(42)); - assertEquals(21, root.call(43)); - } - - @NodeChild - @NodeField(name = "field", type = int.class) - static class TestCacheNodeField extends ValueNode { - - @Specialization - static int do1(int value, @Cached("field") int cachedValue) { - return cachedValue; - } - - } - - @Test - public void testCacheMethod() { - TestCacheMethod.invocations = 0; - CallTarget root = createCallTarget(TestCacheMethodFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(43)); - assertEquals(42, root.call(44)); - assertEquals(1, TestCacheMethod.invocations); - } - - @NodeChild - static class TestCacheMethod extends ValueNode { - - static int invocations = 0; - - @Specialization - static int do1(int value, @Cached("someMethod(value)") int cachedValue) { - return cachedValue; - } - - static int someMethod(int value) { - invocations++; - return value; - } - - } - - @Test - public void testGuardWithJustCachedParameter() { - TestGuardWithJustCachedParameter.invocations = 0; - CallTarget root = createCallTarget(TestGuardWithJustCachedParameterFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(43)); - assertEquals(42, root.call(44)); - // guards with just cached parameters are just invoked on the slow path - assertEquals(assertionsEnabled() ? 4 : 1, TestGuardWithJustCachedParameter.invocations); - } - - @NodeChild - static class TestGuardWithJustCachedParameter extends ValueNode { - - static int invocations = 0; - - @Specialization(guards = "someMethod(cachedValue)") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - static boolean someMethod(int value) { - invocations++; - return true; - } - - } - - @Test - public void testGuardWithCachedAndDynamicParameter() { - TestGuardWithCachedAndDynamicParameter.cachedMethodInvocations = 0; - TestGuardWithCachedAndDynamicParameter.dynamicMethodInvocations = 0; - CallTarget root = createCallTarget(TestGuardWithCachedAndDynamicParameterFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(42, root.call(43)); - assertEquals(42, root.call(44)); - // guards with just cached parameters are just invoked on the slow path - assertEquals(assertionsEnabled() ? 4 : 1, TestGuardWithCachedAndDynamicParameter.cachedMethodInvocations); - assertEquals(4, TestGuardWithCachedAndDynamicParameter.dynamicMethodInvocations); - } - - @NodeChild - static class TestGuardWithCachedAndDynamicParameter extends ValueNode { - - static int cachedMethodInvocations = 0; - static int dynamicMethodInvocations = 0; - - @Specialization(guards = {"dynamicMethod(value)", "cachedMethod(cachedValue)"}) - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - static boolean cachedMethod(int value) { - cachedMethodInvocations++; - return true; - } - - static boolean dynamicMethod(int value) { - dynamicMethodInvocations++; - return true; - } - - } - - /* - * Node should not produce any warnings in isIdentical of the generated code. Unnecessary casts - * were generated for isIdentical on the fast path. - */ - @NodeChildren({@NodeChild, @NodeChild}) - static class RegressionTestWarningInIsIdentical extends ValueNode { - - @Specialization(guards = {"cachedName == name"}) - protected Object directAccess(String receiver, String name, // - @Cached("name") String cachedName, // - @Cached("create(receiver, name)") Object callHandle) { - return receiver; - } - - protected static Object create(String receiver, String name) { - return receiver; - } - - } - - @NodeChild - static class TestMultipleCaches extends ValueNode { - - @Specialization - static int do1(int value, @Cached("value") int cachedValue1, @Cached("value") int cachedValue2) { - return cachedValue1 + cachedValue2; - } - - } - - @Test - public void testMultipleCaches() { - CallTarget root = createCallTarget(TestMultipleCachesFactory.getInstance()); - assertEquals(42, root.call(21)); - assertEquals(42, root.call(22)); - assertEquals(42, root.call(23)); - } - - @NodeChild - static class CachedError1 extends ValueNode { - @Specialization - static int do1(int value, @ExpectError("Incompatible return type int. The expression type must be equal to the parameter type double.")// - @Cached("value") double cachedValue) { - return value; - } - } - - @NodeChild - static class CachedError2 extends ValueNode { - - // caches are not allowed to make backward references - - @Specialization - static int do1(int value, - @ExpectError("The initializer expression of parameter 'cachedValue1' binds unitialized parameter 'cachedValue2. Reorder the parameters to resolve the problem.") @Cached("cachedValue2") int cachedValue1, - @Cached("value") int cachedValue2) { - return cachedValue1 + cachedValue2; - } - - } - - @NodeChild - static class CachedError3 extends ValueNode { - - // cyclic dependency between cached expressions - @Specialization - static int do1(int value, - @ExpectError("The initializer expression of parameter 'cachedValue1' binds unitialized parameter 'cachedValue2. Reorder the parameters to resolve the problem.") @Cached("cachedValue2") int cachedValue1, - @Cached("cachedValue1") int cachedValue2) { - return cachedValue1 + cachedValue2; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CodeFormatTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CodeFormatTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +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.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.CodeFormatTestFactory.LineWrappingTestFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -/** - * Tests the generated code compiles without warnings for unusual large guard names. - */ -public class CodeFormatTest { - - @Test - public void test() { - Assert.assertEquals(42, TestHelper.createCallTarget(LineWrappingTestFactory.create()).call()); - } - - abstract static class LineWrappingTest extends ValueNode { - - public LineWrappingTest() { - } - - protected static boolean guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName1() { - return true; - } - - protected static boolean guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName2() { - return true; - } - - @Specialization(guards = {"guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName1()", - "guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName2()", - "guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName1()", - "guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName2()", - "guardWithaReeeeeeeeaaaaaaaaaaalllllllllyyyyyyyyLLLLLLLLLLLLLoooooooonnnnnnngggggggName1()"}) - public int execute() { - return 42; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CompilerErrorTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CompilerErrorTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class CompilerErrorTest { - - abstract static class Visiblity01 extends ValueNode { - - @Specialization - @SuppressWarnings("static-method") - @ExpectError("Method annotated with @Specialization must not be private.") - private Object s() { - return null; - } - - } - - @ExpectError("Classes containing a @Specialization annotation must not be private.") - private abstract static class Visiblity02 extends ValueNode { - - @Specialization - public Object s() { - return null; - } - - } - - // assert no error - @ExpectError({}) - private abstract static class Visiblity03 extends ValueNode { - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ContainsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,555 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains1Factory; -import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains2Factory; -import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains3Factory; -import com.oracle.truffle.api.dsl.test.ContainsTestFactory.Contains4Factory; -import com.oracle.truffle.api.dsl.test.ContainsTestFactory.PolymorphicToMonomorphic0Factory; -import com.oracle.truffle.api.dsl.test.TestHelper.ExecutionListener; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; - -@SuppressWarnings("unused") -public class ContainsTest { - - /* - * Tests a simple monomorphic inclusion. - */ - @Test - public void testContains1() { - assertRuns(Contains1Factory.getInstance(), // - array(1, "a", 2, "b"), // - array(2, "aa", 3, "ba"), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (value instanceof String) { - if (node.getNode() instanceof DSLNode) { - // assert that the final specialization is always Object - Assert.assertEquals(Object.class, ((DSLNode) node.getNode()).getMetadata0().getSpecializedTypes()[0]); - } else { - Assert.assertTrue(((SpecializedNode) node.getNode()).getSpecializationNode().toString().startsWith("F2Node_")); - } - } - } - }); - } - - @NodeChild("a") - abstract static class Contains1 extends ValueNode { - - @Specialization - int f1(int a) { - return a + 1; - } - - @Specialization(contains = "f1") - Object f2(Object a) { - if (a instanceof Integer) { - return ((Integer) a) + 1; - } - return a + "a"; - } - } - - /* - * Tests an inclusion in within a polymorphic chain. - */ - @Test - public void testContains2() { - assertRuns(Contains2Factory.getInstance(), // - array(true, 1, 0, false), // - array(false, -1, 1, true) // - ); - } - - @NodeChild("a") - abstract static class Contains2 extends ValueNode { - - static boolean isZero(int a) { - return a == 0; - } - - @Specialization(guards = "isZero(a)") - int f1(int a) { - return a + 1; - } - - @Specialization(contains = "f1") - int f2(int a) { - if (a == 0) { - return a + 1; - } - return -a; - } - - @Specialization - boolean f3(boolean a) { - return !a; - } - } - - /* - * Tests transitive monomorphic inclusion. - */ - @Test - public void testContains3() { - assertRuns(Contains3Factory.getInstance(), // - array(2, 1, 2, -3, -4), // - array(-2, 2, -2, -3, -4), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - // assert that we are always monomorphic - Assert.assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); - } - }); - } - - @NodeChild("a") - abstract static class Contains3 extends ValueNode { - - static boolean isGreaterZero(int a) { - return a > 0; - } - - static boolean isOne(int a) { - return a == 1; - } - - @Specialization(guards = {"isOne(a)"}) - int f1(int a) { - return a + 1; - } - - @Specialization(contains = "f1", guards = {"isGreaterZero(a)"}) - int f2(int a) { - if (a == 1) { - return 2; - } - return -a; - } - - @Specialization(contains = "f2") - int f3(int a) { - if (a > 0) { - return a == 1 ? 2 : -a; - } else { - return a; - } - } - - } - - /* - * Tests that if it can be derived that two specializations actually a as powerful as the latter - * we can combine them. Therefore operation should always become monomorphic in the end. - */ - @Test - public void testContains4() { - assertRuns(Contains4Factory.getInstance(), // - array(-1, 0, 1, 2), // - array(1, 0, 1, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - Assert.assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); - } - }); - } - - @NodeChild("a") - abstract static class Contains4 extends ValueNode { - - static boolean isOne(int a) { - return a == 1; - } - - @Specialization(guards = "isOne(a)") - int f0(int a) { - return 1; - } - - @Specialization(contains = "f0", guards = "a >= 0") - int f1(int a) { - return a; - } - - @Specialization(contains = {"f1"}) - int f2(int a) { - return Math.abs(a); - } - - } - - @NodeChild("a") - abstract static class ContainsError1 extends ValueNode { - @ExpectError("The contained specialization 'f1' must be declared before the containing specialization.") - @Specialization(contains = "f1") - int f0(int a) { - return a; - } - - @Specialization - Object f1(String a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsError2 extends ValueNode { - - @ExpectError("The referenced specialization 'does not exist' could not be found.") - @Specialization(contains = "does not exist") - int f0(int a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsError3 extends ValueNode { - - @Specialization - int f0(int a) { - return a; - } - - @ExpectError("Duplicate contains declaration 'f0'.") - @Specialization(contains = {"f0", "f0"}) - Object f1(double a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsError4 extends ValueNode { - - @ExpectError("Circular contained specialization 'f1(double)' found.") - @Specialization(contains = {"f1"}) - Object f1(double a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsError5 extends ValueNode { - - @ExpectError({"Circular contained specialization 'f0(int)' found.", "Circular contained specialization 'f1(double)' found.", - "The contained specialization 'f1' must be declared before the containing specialization."}) - @Specialization(contains = "f1") - int f0(int a) { - return a; - } - - @ExpectError("Circular contained specialization 'f1(double)' found.") - @Specialization(contains = {"f0"}) - Object f1(double a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsType1 extends ValueNode { - @Specialization - int f0(int a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by f0(int).") - @Specialization(contains = "f0") - Object f1(int a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsType2 extends ValueNode { - @Specialization - int f0(int a) { - return a; - } - - @Specialization(contains = "f0") - Object f1(Object a) { - return a; - } - } - - @NodeChild("a") - abstract static class ContainsType3 extends ValueNode { - @Specialization - int f0(int a) { - return a; - } - - @Specialization(contains = "f0") - Object f1(double a) { // implicit type - return a; - } - } - - @NodeChild("a") - abstract static class ContainsType4 extends ValueNode { - @Specialization - double f0(double a) { - return a; - } - - @ExpectError({"Specialization is not reachable. It is shadowed by f0(double)."}) - @Specialization(contains = "f0") - int f1(int a) { // implicit type - return a; - } - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class ContainsType5 extends ValueNode { - @Specialization - Object f0(Object a, int b) { - return a; - } - - @Specialization(contains = "f0") - Object f1(int a, Object b) { - return a; - } - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class ContainsType6 extends ValueNode { - @Specialization - Object f0(double a, int b) { - return a; - } - - @Specialization(contains = "f0") - Object f1(int a, double b) { // implicit type - return a; - } - } - - abstract static class ContainsGuard1 extends ValueNode { - - boolean g1() { - return true; - } - - @Specialization(guards = "g1()") - Object f0() { - return null; - } - - @Specialization(contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard2 extends ValueNode { - - boolean g1() { - return true; - } - - @Specialization - Object f0() { - return null; - } - - @ExpectError({"Specialization is not reachable. It is shadowed by f0()."}) - @Specialization(guards = "g1()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard3 extends ValueNode { - - boolean g1() { - return true; - } - - @Specialization(guards = "g1()") - Object f0() { - return null; - } - - @Specialization(guards = "!g1()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard4 extends ValueNode { - - boolean g1() { - return true; - } - - boolean g2() { - return true; - } - - @Specialization(guards = "g1()") - Object f0() { - return null; - } - - @Specialization(guards = "g2()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard5 extends ValueNode { - - boolean g1() { - return true; - } - - boolean g2() { - return true; - } - - @Specialization(guards = "g1()") - Object f0() { - return null; - } - - @Specialization(guards = "g2()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard6 extends ValueNode { - - boolean g1() { - return true; - } - - boolean g2() { - return true; - } - - @Specialization(guards = "g1()") - Object f0() { - return null; - } - - @Specialization(guards = "!g2()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsGuard7 extends ValueNode { - - boolean g1() { - return true; - } - - boolean g2() { - return true; - } - - @Specialization(guards = {"g1()", "g2()"}) - Object f0() { - return null; - } - - @Specialization(guards = "g2()", contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsThrowable1 extends ValueNode { - - @Specialization(rewriteOn = RuntimeException.class) - Object f0() throws RuntimeException { - throw new RuntimeException(); - } - - @Specialization(contains = "f0") - Object f1() { - return null; - } - } - - abstract static class ContainsThrowable2 extends ValueNode { - - @Specialization(rewriteOn = RuntimeException.class) - Object f0() throws RuntimeException { - throw new RuntimeException(); - } - - @Specialization(contains = "f0", rewriteOn = RuntimeException.class) - Object f1() throws RuntimeException { - throw new RuntimeException(); - } - - @Specialization(contains = "f1") - Object f2() { - return null; - } - } - - @Test - public void testPolymorphicToMonomorphic0() { - TestRootNode root = createRoot(PolymorphicToMonomorphic0Factory.getInstance()); - assertThat((int) executeWith(root, 1), is(1)); - assertThat((int) executeWith(root, 2), is(2)); - assertThat((int) executeWith(root, 3), is(3)); - assertThat(root.getNode().getCost(), is(NodeCost.MONOMORPHIC)); - } - - @NodeChild("a") - static class PolymorphicToMonomorphic0 extends ValueNode { - - @Specialization(guards = "a == 1") - int do1(int a) { - return a; - } - - @Specialization(guards = "a == 2") - int do2(int a) { - return a; - } - - @Specialization(contains = {"do1", "do2"}) - int do3(int a) { - return a; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CreateCastTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CreateCastTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.CreateCastTestFactory.CreateCastNode1Factory; -import com.oracle.truffle.api.dsl.test.CreateCastTestFactory.CreateCastNode2Factory; -import com.oracle.truffle.api.dsl.test.CreateCastTestFactory.CreateCastNode3Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; - -@SuppressWarnings("unused") -public class CreateCastTest { - - @Test - public void testCastNode1() { - TestRootNode root = TestHelper.createRoot(CreateCastNode1Factory.getInstance()); - Assert.assertEquals(1, root.getNode().invocations); - } - - @Test - public void testCastNode2() { - TestRootNode root = TestHelper.createRoot(CreateCastNode2Factory.getInstance()); - Assert.assertEquals(2, root.getNode().invocations); - } - - @Test - public void testCastNode3() { - TestRootNode root = TestHelper.createRoot(CreateCastNode3Factory.getInstance()); - Assert.assertEquals(1, root.getNode().invocations); - } - - @NodeChild("a") - abstract static class CreateCastNode1 extends ValueNode { - - int invocations = 0; - - @CreateCast({"a"}) - public ValueNode createCast(ValueNode node) { - invocations++; - return node; - } - - @Specialization - public int doInteger(int a) { - throw new AssertionError(); - } - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class CreateCastNode2 extends ValueNode { - - int invocations = 0; - - @CreateCast({"a", "b"}) - public ValueNode createCast(ValueNode node) { - invocations++; - return node; - } - - @Specialization - public int doInteger(int a, int b) { - throw new AssertionError(); - } - } - - abstract static class CreateCastNode3 extends ChildrenNode { - - int invocations = 0; - - @CreateCast("children") - public ValueNode[] createCast(ValueNode[] node) { - invocations++; - return node; - } - - @Specialization - public int doInteger(int a) { - throw new AssertionError(); - } - } - - @NodeChild("a") - abstract static class CreateCastFailNode1 extends ValueNode { - - @ExpectError({"Specified child '' not found."}) - @CreateCast({""}) - public ValueNode createCast(Node child) { - throw new AssertionError(); - } - - @Specialization - public int doInteger(int a) { - throw new AssertionError(); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.DoubleEvaluatedNodeFactory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.EvaluatedNodeFactory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedGenerationFactory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs0Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs1Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs2Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs3Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs4Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs5Factory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluated1NodeFactory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluated2NodeFactory; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public class ExecuteEvaluatedTest { - - @Test - public void testSingleEvaluated() { - ArgumentNode arg0 = new ArgumentNode(0); - CallTarget callTarget = TestHelper.createCallTarget(UseEvaluatedNodeFactory.create(arg0, EvaluatedNodeFactory.create(null))); - - Assert.assertEquals(43, callTarget.call(new Object[]{42})); - Assert.assertEquals(1, arg0.getInvocationCount()); - } - - @NodeChild("exp") - abstract static class EvaluatedNode extends ValueNode { - - @Specialization - int doExecuteWith(int exp) { - return exp + 1; - } - - public abstract Object executeEvaluated(VirtualFrame frame, Object targetValue); - - public abstract int executeIntEvaluated(VirtualFrame frame, Object targetValue) throws UnexpectedResultException; - } - - @NodeChildren({@NodeChild("exp0"), @NodeChild(value = "exp1", type = EvaluatedNode.class, executeWith = "exp0")}) - abstract static class UseEvaluatedNode extends ValueNode { - - @Specialization - int call(int exp0, int exp1) { - Assert.assertEquals(exp0 + 1, exp1); - return exp1; - } - } - - @Test - public void testDoubleEvaluated1() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluated1NodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null))); - - Assert.assertEquals(42, callTarget.call(new Object[]{43, 1})); - Assert.assertEquals(1, arg0.getInvocationCount()); - Assert.assertEquals(1, arg1.getInvocationCount()); - } - - @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1")}) - abstract static class DoubleEvaluatedNode extends ValueNode { - - @Specialization - int doExecuteWith(int exp0, int exp1) { - return exp0 - exp1; - } - - public abstract Object executeEvaluated(VirtualFrame frame, Object exp0, Object exp1); - - public abstract int executeIntEvaluated(VirtualFrame frame, Object exp0, Object exp1) throws UnexpectedResultException; - } - - @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp0", "exp1"})}) - abstract static class UseDoubleEvaluated1Node extends ValueNode { - - @Specialization - int call(int exp0, int exp1, int exp2) { - Assert.assertEquals(exp0 - exp1, exp2); - return exp2; - } - } - - @Test - public void testDoubleEvaluated2() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluated2NodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null))); - - Assert.assertEquals(42, callTarget.call(new Object[]{1, 43})); - Assert.assertEquals(1, arg0.getInvocationCount()); - Assert.assertEquals(1, arg1.getInvocationCount()); - } - - @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp1", "exp0"})}) - abstract static class UseDoubleEvaluated2Node extends ValueNode { - - @Specialization - int call(int exp0, int exp1, int exp2) { - Assert.assertEquals(exp1 - exp0, exp2); - return exp2; - } - } - - @Test - public void testEvaluatedGeneration() throws UnexpectedResultException { - TestRootNode root = TestHelper.createRoot(TestEvaluatedGenerationFactory.getInstance()); - - Assert.assertEquals(42, root.getNode().executeEvaluated1(null, 42)); - Assert.assertEquals(42, root.getNode().executeEvaluated2(null, 42)); - Assert.assertEquals(42, root.getNode().executeEvaluated3(null, 42)); - Assert.assertEquals(42, root.getNode().executeEvaluated4(null, 42)); - } - - @NodeChildren({@NodeChild("exp0")}) - abstract static class TestEvaluatedGeneration extends ValueNode { - - public abstract Object executeEvaluated1(VirtualFrame frame, Object value); - - public abstract Object executeEvaluated2(VirtualFrame frame, int value); - - public abstract int executeEvaluated3(VirtualFrame frame, Object value) throws UnexpectedResultException; - - public abstract int executeEvaluated4(VirtualFrame frame, int value) throws UnexpectedResultException; - - @Specialization - int call(int exp0) { - return exp0; - } - } - - @Test - public void test0VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs0Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null)); - } - - abstract static class TestEvaluatedVarArgs0 extends ChildrenNode { - - @Override - public final Object execute(VirtualFrame frame) { - return execute1(frame); - } - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call() { - return 42; - } - } - - @Test - public void test1VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs1Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null, 42)); - } - - @Test(expected = Throwable.class) - public void test1VarArgs2() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); - root.getNode().execute1(null); - } - - abstract static class TestEvaluatedVarArgs1 extends ChildrenNode { - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call(int exp0) { - return exp0; - } - } - - @Test - public void test2VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null, 21, 21)); - } - - @Test(expected = Throwable.class) - public void test2VarArgs2() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); - root.getNode().execute1(null, 42); - } - - @Test(expected = Throwable.class) - public void test2VarArgs3() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); - root.getNode().execute1(null); - } - - abstract static class TestEvaluatedVarArgs2 extends ChildrenNode { - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call(int exp0, int exp1) { - return exp0 + exp1; - } - } - - @Test - public void test3VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs3Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null, 42)); - } - - @NodeChild - abstract static class TestEvaluatedVarArgs3 extends ValueNode { - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call(int exp0) { - return exp0; - } - } - - @Test - public void test4VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs4Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null, 21, 21)); - } - - @NodeChildren({@NodeChild, @NodeChild}) - abstract static class TestEvaluatedVarArgs4 extends ValueNode { - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call(int exp0, int exp1) { - return exp0 + exp1; - } - } - - @Test - public void test5VarArgs1() { - TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs5Factory.getInstance()); - Assert.assertEquals(42, root.getNode().execute1(null)); - } - - abstract static class TestEvaluatedVarArgs5 extends ValueNode { - - @Override - public final Object execute(VirtualFrame frame) { - return execute1(frame); - } - - public abstract Object execute1(VirtualFrame frame, Object... value); - - @Specialization - int call() { - return 42; - } - } - - @SuppressWarnings("unused") - @NodeChildren({@NodeChild(value = "a", type = ValueNode.class), @NodeChild(value = "b", type = ValueNode.class)}) - abstract static class TestEvaluatedShortCircuit1 extends Node { - - public abstract Object execute1(VirtualFrame frame, Object value); - - public abstract Object execute2(VirtualFrame frame, Object value, boolean hasB); - - public abstract Object execute3(VirtualFrame frame, Object value, boolean hasB, Object b); - - @ShortCircuit("b") - public boolean needsB(Object a) { - return true; - } - - @Specialization - int call(Object a, boolean hasB, Object b) { - return 42; - } - } - - @SuppressWarnings("unused") - @NodeChildren({@NodeChild(value = "a", type = ValueNode.class), @NodeChild(value = "b", type = ValueNode.class)}) - abstract static class TestEvaluatedShortCircuit2 extends Node { - - public abstract Object execute1(VirtualFrame frame, Object value); - - public abstract Object execute2(VirtualFrame frame, Object value, boolean hasB); - - public abstract Object execute3(VirtualFrame frame, Object value, boolean hasB, Object b); - - @ShortCircuit("b") - public boolean needsB(Object a) { - return true; - } - - @Specialization - int call(int a, boolean hasB, int b) { - return 42; - } - - @Specialization - int call(Object a, boolean hasB, Object b) { - return 42; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteGroupingTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteGroupingTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +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.dsl.test; - -import static org.junit.Assert.*; - -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ExecuteGroupingTestFactory.ExecuteGrouping1NodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/* - * This test aims to test the reuse of execute methods with evaluated parameters as much as possible. - */ -@RunWith(Theories.class) -public class ExecuteGroupingTest { - - @DataPoints public static final Object[] parameters = new Object[]{1, 2}; - - static final class ExecuteGroupingChild extends Node { - - int invocationCount = 0; - - private final Object returnValue; - - public ExecuteGroupingChild(Object returnValue) { - this.returnValue = returnValue; - } - - Object execute() { - invocationCount++; - return returnValue; - } - - } - - @Theory - public void testExecuteGrouping1Node(Object a, Object b, Object c) throws UnexpectedResultException { - ExecuteGroupingChild child0 = new ExecuteGroupingChild(a); - ExecuteGroupingChild child1 = new ExecuteGroupingChild(b); - ExecuteGroupingChild child2 = new ExecuteGroupingChild(c); - - int result = ((int) a) + ((int) b) + ((int) c); - - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(child0, child1, child2)).execute()); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(child0, child1, child2)).execute((VirtualFrame) null)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, child1, child2)).execute(a)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, child1, child2)).executeInt(a)); - - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, child2)).execute(a, b)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, child2)).execute((int) a, b)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, child2)).execute(a, (int) b)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, child2)).execute((int) a, (int) b)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, child2)).executeInt((int) a, (int) b)); - - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, null)).execute(a, b, c)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, null)).execute((int) a, (int) b, c)); - assertEquals(result, TestHelper.createRoot(ExecuteGrouping1NodeGen.create(null, null, null)).execute((int) a, (int) b, (int) c)); - - } - - @NodeChildren({@NodeChild(type = ExecuteGroupingChild.class), @NodeChild(type = ExecuteGroupingChild.class), @NodeChild(type = ExecuteGroupingChild.class)}) - abstract static class ExecuteGrouping1Node extends Node { - - abstract Object execute(); - - int executeInt() throws UnexpectedResultException { - Object value = execute(); - if (value instanceof Integer) { - return (int) value; - } - throw new UnexpectedResultException(value); - } - - abstract double executeDouble() throws UnexpectedResultException; - - abstract Object execute(VirtualFrame frame); - - abstract Object execute(Object o1); - - abstract int executeInt(Object o1) throws UnexpectedResultException; - - abstract Object execute(Object o1, Object o2); - - abstract Object execute(int o1, int o2); - - abstract Object execute(int o1, int o2, Object o3); - - abstract int executeInt(int o1, int o2) throws UnexpectedResultException; - - abstract Object execute(Object o1, int o2); - - abstract Object execute(int o1, Object o2); - - abstract Object execute(Object o1, Object o2, Object o3); - - abstract Object execute(int o1, int o2, int o3); - - @Specialization - int s1(int a, int b, int c) { - return a + b + c; - } - - @Specialization - int s2(Object a, Object b, Object c) { - return ((int) a) + ((int) b) + ((int) c); - } - - } - - abstract static class StrangeReturnCase extends Node { - - // we don't know how to implement executeDouble - public abstract double executeDouble(); - - public int executeInt() { - return 42; - } - - @Specialization(rewriteOn = RuntimeException.class) - double s1() { - return 42; - } - - @Specialization - double s2() { - return 42; - } - - } - - @ExpectError("Incompatible abstract execute methods found %") - abstract static class IncompatibleAbstract1 extends Node { - - // we don't know how to implement executeDouble - abstract double executeDouble(); - - abstract int executeInt(); - - @Specialization - double s1() { - return 42; - } - - } - - abstract static class IncompatibleAbstract2 extends Node { - - abstract double executeDouble(); - - // we can resolve duplicate path errors by making an execute method final - @SuppressWarnings("static-method") - public final int executeInt() { - return 42; - } - - @ExpectError("The provided return type \"int\" does not match expected return type \"double\".%") - @Specialization(rewriteOn = RuntimeException.class) - int s1() { - return 42; - } - - @Specialization - double s2() { - return 42; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteMethodTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteMethodTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,433 +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.dsl.test; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public class ExecuteMethodTest { - - private static final String ERROR_NO_EXECUTE = "No accessible and overridable generic execute method found. Generic execute methods usually have the signature 'public abstract {Type} " - + "execute(VirtualFrame)' and must not throw any checked exceptions."; - - @TypeSystem({int.class}) - @DSLOptions(useNewLayout = true) - static class ExecuteMethodTypes { - } - - @TypeSystemReference(ExecuteMethodTypes.class) - abstract static class ChildNoFrame extends Node { - abstract Object execute(); - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError(ERROR_NO_EXECUTE) - abstract static class ExecuteThis1 extends Node { - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError(ERROR_NO_EXECUTE) - abstract static class ExecuteThis2 extends Node { - - abstract Object execute() throws UnexpectedResultException; - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError(ERROR_NO_EXECUTE) - abstract static class ExecuteThis3 extends Node { - - abstract int execute() throws UnexpectedResultException; - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThis4 extends Node { - - protected abstract Object execute(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThis5 extends Node { - - public abstract Object execute(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError(ERROR_NO_EXECUTE) - abstract static class ExecuteThis6 extends Node { - - @SuppressWarnings({"unused", "static-method"}) - private Object execute() { - return 0; - } - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError(ERROR_NO_EXECUTE) - abstract static class ExecuteThis7 extends Node { - - @SuppressWarnings("static-method") - public final int executeInt() { - return 0; - } - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThis8 extends Node { - - abstract int executeInt(); - - abstract Object executeObject(); - - @Specialization - int doInt(int a) { - return a; - } - - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThis9 extends Node { - - abstract int executeInt(); - - // disambiguate executeObject - final Object executeObject() { - return executeInt(); - } - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThisVoid1 extends Node { - - abstract void executeVoid(); - - @Specialization - void doInt(@SuppressWarnings("unused") int a) { - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThisVoid2 extends Node { - - // allow one execute void - abstract void executeVoid(); - - abstract Object executeObject(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteThisVoid3 extends Node { - - // allow only one execute void - abstract void executeVoid1(); - - abstract void executeVoid2(); - - abstract Object executeObject(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrame1 extends Node { - - // no frame in execute. no parameter in specializations - abstract Object executeNoFrame(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrame2 extends Node { - - // frame in execute also usable in specialization - abstract Object executeWithFrame(VirtualFrame frame); - - @Specialization - int doInt(@SuppressWarnings("unused") VirtualFrame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrame3 extends Node { - - abstract Object executeWithFrame(Frame frame); - - @Specialization - int doInt(@SuppressWarnings("unused") Frame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ExecuteWithFrame4.class) - abstract static class ExecuteWithFrame4 extends Node { - - abstract Object executeWithFrame(MaterializedFrame frame); - - @Specialization - int doInt(@SuppressWarnings("unused") MaterializedFrame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrameError1 extends Node { - - abstract Object executeNoFrame(); - - @Specialization - @ExpectError("Method signature (VirtualFrame, int) does not match to the expected signature:%") - int doInt(@SuppressWarnings("unused") VirtualFrame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrameError2 extends Node { - - abstract Object executeFrame(MaterializedFrame frame); - - @Specialization - @ExpectError("Method signature (VirtualFrame, int) does not match to the expected signature:%") - int doInt(@SuppressWarnings("unused") VirtualFrame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrameError3 extends Node { - - abstract Object executeFrame(VirtualFrame frame); - - @Specialization - @ExpectError("Method signature (MaterializedFrame, int) does not match to the expected signature:%") - int doInt(@SuppressWarnings("unused") MaterializedFrame frame, int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - @ExpectError("Invalid inconsistent frame types [MaterializedFrame, VirtualFrame] found for the declared execute methods.%") - abstract static class ExecuteWithFrameError4 extends Node { - - abstract Object execute(VirtualFrame frame); - - abstract int executeInt(MaterializedFrame frame) throws UnexpectedResultException; - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteWithFrameError5 extends Node { - - abstract Object execute(); - - abstract int executeInt(MaterializedFrame frame) throws UnexpectedResultException; - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - abstract static class ChildVirtualFrame extends Node { - abstract Object execute(VirtualFrame frame); - } - - @TypeSystemReference(ExecuteMethodTypes.class) - abstract static class ChildMaterializedFrame extends Node { - abstract Object execute(MaterializedFrame frame); - } - - @TypeSystemReference(ExecuteMethodTypes.class) - abstract static class ChildFrame extends Node { - abstract Object execute(Frame frame); - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildNoFrame.class) - abstract static class ExecuteChildFrame1 extends Node { - - abstract Object execute(VirtualFrame frame); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildFrame.class) - abstract static class ExecuteChildFrame2 extends Node { - - abstract Object execute(VirtualFrame frame); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildFrame.class) - abstract static class ExecuteChildFrame3 extends Node { - - abstract Object execute(MaterializedFrame frame); - - @Specialization - int doInt(int a) { - return a; - } - } - - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildFrame.class) - abstract static class ExecuteChildFrame4 extends Node { - - abstract Object execute(Frame frame); - - @Specialization - int doInt(int a) { - return a; - } - } - - @ExpectError("No generic execute method found with 0 evaluated arguments for node type ChildVirtualFrame and frame types [com.oracle.truffle.api.frame.Frame].") - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildVirtualFrame.class) - abstract static class ExecuteChildFrameError1 extends Node { - - abstract Object execute(Frame frame); - - @Specialization - int doInt(int a) { - return a; - } - } - - @ExpectError("No generic execute method found with 0 evaluated arguments for node type ChildFrame and frame types [].") - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildFrame.class) - abstract static class ExecuteChildFrameError2 extends Node { - - abstract Object execute(); - - @Specialization - int doInt(int a) { - return a; - } - } - - @ExpectError("No generic execute method found with 0 evaluated arguments for node type ChildVirtualFrame and frame types [].") - @TypeSystemReference(ExecuteMethodTypes.class) - @NodeChild(value = "a", type = ChildVirtualFrame.class) - abstract static class ExecuteChildFrameError3 extends Node { - - abstract Object execute(); - - @Specialization - int doInt(int a) { - return a; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExpectError.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExpectError.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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.dsl.test; - -import java.lang.annotation.*; - -/** - * This annotation is internally known by the dsl processor and used to expect errors for testing - * purposes. This is not part of public API. - */ -@Retention(RetentionPolicy.RUNTIME) -public @interface ExpectError { - - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/FallbackTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/FallbackTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback1Factory; -import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback2Factory; -import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback3Factory; -import com.oracle.truffle.api.dsl.test.FallbackTestFactory.Fallback4Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public class FallbackTest { - - private static final Object UNKNOWN_OBJECT = new Object() { - }; - - @Test - public void testFallback1() { - assertRuns(Fallback1Factory.getInstance(), // - array(42, UNKNOWN_OBJECT), // - array("(int)", "(fallback)")); - } - - /** - * Test with fallback handler defined. - */ - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class Fallback1 extends ValueNode { - - @Override - public abstract String executeString(VirtualFrame frame); - - @Specialization - String f1(int a) { - return "(int)"; - } - - @Fallback - String f2(Object a) { - return "(fallback)"; - } - } - - @Test - public void testFallback2() { - assertRuns(Fallback2Factory.getInstance(), // - array(42, UNKNOWN_OBJECT), // - array("(int)", UnsupportedSpecializationException.class)); - } - - /** - * Test without fallback handler defined. - */ - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class Fallback2 extends ValueNode { - - @Specialization - String f1(int a) { - return "(int)"; - } - - } - - @Test - public void testFallback3() { - assertRuns(Fallback3Factory.getInstance(), // - array(42, 43, UNKNOWN_OBJECT, "somestring"), // - array("(int)", "(int)", "(object)", "(object)")); - } - - /** - * Test without fallback handler and unreachable. - */ - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class Fallback3 extends ValueNode { - - @Specialization - String f1(int a) { - return "(int)"; - } - - @Specialization(guards = "notInt(a)") - String f2(Object a) { - return "(object)"; - } - - boolean notInt(Object value) { - return !(value instanceof Integer); - } - - } - - /** - * Tests the contents of the {@link UnsupportedSpecializationException} contents in polymorphic - * nodes. - */ - @Test - public void testFallback4() { - TestRootNode node = createRoot(Fallback4Factory.getInstance()); - - Assert.assertEquals("(int)", executeWith(node, 1)); - Assert.assertEquals("(boolean)", executeWith(node, true)); - try { - executeWith(node, UNKNOWN_OBJECT); - Assert.fail(); - } catch (UnsupportedSpecializationException e) { - Assert.assertEquals(node.getNode(), e.getNode()); - Assert.assertArrayEquals(NodeUtil.findNodeChildren(node.getNode()).subList(0, 1).toArray(new Node[0]), e.getSuppliedNodes()); - Assert.assertArrayEquals(new Object[]{UNKNOWN_OBJECT}, e.getSuppliedValues()); - } - } - - /** - * Test without fallback handler and unreachable. - */ - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class Fallback4 extends ValueNode { - - @Specialization - String f1(int a) { - return "(int)"; - } - - @Specialization - String f2(boolean a) { - return "(boolean)"; - } - } - - /** - * Tests the contents of the {@link UnsupportedSpecializationException} contents in monomorphic - * nodes. - */ - @Test - public void testFallback5() { - TestRootNode node = createRoot(Fallback4Factory.getInstance()); - - Assert.assertEquals("(int)", executeWith(node, 1)); - try { - executeWith(node, UNKNOWN_OBJECT); - Assert.fail(); - } catch (UnsupportedSpecializationException e) { - Assert.assertEquals(node.getNode(), e.getNode()); - Assert.assertArrayEquals(NodeUtil.findNodeChildren(node.getNode()).subList(0, 1).toArray(new Node[0]), e.getSuppliedNodes()); - Assert.assertArrayEquals(new Object[]{UNKNOWN_OBJECT}, e.getSuppliedValues()); - } - } - - // test without fallback handler and unreachable - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class Fallback5 extends ValueNode { - - @Specialization - String f1(int a) { - return "(int)"; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +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.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast0NodeFactory; -import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast1NodeFactory; -import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast2NodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; - -public class ImplicitCastTest { - - @TypeSystem({int.class, String.class, boolean.class}) - static class ImplicitCast0Types { - - @ImplicitCast - static boolean castInt(int intvalue) { - return intvalue == 1 ? true : false; - } - - @ImplicitCast - static boolean castString(String strvalue) { - return strvalue.equals("1"); - } - - } - - @TypeSystemReference(ImplicitCast0Types.class) - @NodeChild(value = "operand", type = ImplicitCast0Node.class) - abstract static class ImplicitCast0Node extends ValueNode { - - public abstract Object executeEvaluated(VirtualFrame frame, Object value2); - - @Specialization - public String op1(String value) { - return value; - } - - @Specialization - public boolean op1(boolean value) { - return value; - } - - } - - @Test - public void testImplicitCast0() { - ImplicitCast0Node node = ImplicitCast0NodeFactory.create(null); - TestRootNode root = new TestRootNode<>(node); - root.adoptChildren(); - Assert.assertEquals("2", root.getNode().executeEvaluated(null, "2")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); - Assert.assertEquals("1", root.getNode().executeEvaluated(null, "1")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, true)); - } - - @TypeSystemReference(ImplicitCast0Types.class) - @NodeChild(value = "operand", type = ImplicitCast1Node.class) - abstract static class ImplicitCast1Node extends ValueNode { - - public abstract Object executeEvaluated(VirtualFrame frame, Object operand); - - @Specialization - public String op0(String value) { - return value; - } - - @Specialization(rewriteOn = RuntimeException.class) - public boolean op1(@SuppressWarnings("unused") boolean value) throws RuntimeException { - throw new RuntimeException(); - } - - @Specialization(contains = "op1") - public boolean op2(boolean value) { - return value; - } - - } - - @Test - public void testImplicitCast1() { - ImplicitCast1Node node = ImplicitCast1NodeFactory.create(null); - TestRootNode root = new TestRootNode<>(node); - root.adoptChildren(); - Assert.assertEquals("2", root.getNode().executeEvaluated(null, "2")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); - Assert.assertEquals("1", root.getNode().executeEvaluated(null, "1")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1)); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, true)); - } - - @TypeSystemReference(ImplicitCast0Types.class) - @NodeChildren({@NodeChild(value = "operand0", type = ImplicitCast2Node.class), @NodeChild(value = "operand1", type = ImplicitCast2Node.class, executeWith = "operand0")}) - // TODO temporary workaround - abstract static class ImplicitCast2Node extends ValueNode { - - @Specialization - public String op0(String v0, String v1) { - return v0 + v1; - } - - @SuppressWarnings("unused") - @Specialization(rewriteOn = RuntimeException.class) - public boolean op1(boolean v0, boolean v1) throws RuntimeException { - throw new RuntimeException(); - } - - @Specialization(contains = "op1") - public boolean op2(boolean v0, boolean v1) { - return v0 && v1; - } - - public abstract Object executeEvaluated(VirtualFrame frame, Object v1); - - public abstract Object executeEvaluated(VirtualFrame frame, Object v1, Object v2); - - public abstract Object executeEvaluated(VirtualFrame frame, boolean v1, boolean v2); - - } - - @Test - public void testImplicitCast2() { - ImplicitCast2Node node = ImplicitCast2NodeFactory.create(null, null); - TestRootNode root = new TestRootNode<>(node); - root.adoptChildren(); - Assert.assertEquals("42", root.getNode().executeEvaluated(null, "4", "2")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1, 1)); - Assert.assertEquals("42", root.getNode().executeEvaluated(null, "4", "2")); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, 1, 1)); - Assert.assertEquals(true, root.getNode().executeEvaluated(null, true, true)); - } - - @TypeSystem({String.class, boolean.class}) - static class ImplicitCastError1 { - - @ImplicitCast - @ExpectError("Target type and source type of an @ImplicitCast must not be the same type.") - static String castInvalid(@SuppressWarnings("unused") String value) { - throw new AssertionError(); - } - - } - - @TypeSystem({String.class, boolean.class}) - static class ImplicitCastError2 { - - @ImplicitCast - @ExpectError("Target type and source type of an @ImplicitCast must not be the same type.") - static String castInvalid(@SuppressWarnings("unused") String value) { - throw new AssertionError(); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImportGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImportGuardsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ImportGuardsTestFactory.ImportGuards6Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class ImportGuardsTest { - - @ImportStatic(Imports0.class) - @NodeChild("a") - static class ImportGuards0 extends ValueNode { - - @Specialization(guards = "staticGuard(a)") - int f0(int a) { - return a; - } - } - - @NodeChild("a") - @ImportStatic(Imports0.class) - static class ImportGuards1 extends ValueNode { - - @ExpectError("Error parsing expression 'nonStaticGuard(a)': The method nonStaticGuard is undefined for the enclosing scope.") - @Specialization(guards = "nonStaticGuard(a)") - int f1(int a) { - return a; - } - - @ExpectError("Error parsing expression 'protectedGuard(a)': The method protectedGuard is undefined for the enclosing scope.") - @Specialization(guards = "protectedGuard(a)") - int f2(int a) { - return a; - } - - @ExpectError("Error parsing expression 'packageGuard(a)': The method packageGuard is undefined for the enclosing scope.") - @Specialization(guards = "packageGuard(a)") - int f3(int a) { - return a; - } - - @ExpectError("Error parsing expression 'privateGuard(a)': The method privateGuard is undefined for the enclosing scope.") - @Specialization(guards = "privateGuard(a)") - int f4(int a) { - return a; - } - } - - public static class Imports0 { - public static boolean staticGuard(int a) { - return a == 0; - } - - public boolean nonStaticGuard(int a) { - return a == 0; - } - - protected static boolean protectedGuard(int a) { - return a == 0; - } - - static boolean packageGuard(int a) { - return a == 0; - } - - @SuppressWarnings("unused") - private static boolean privateGuard(int a) { - return a == 0; - } - - } - - @ExpectError("The specified import guard class 'com.oracle.truffle.api.dsl.test.ImportGuardsTest.Imports1' must be public.") - @NodeChild("a") - @ImportStatic(Imports1.class) - static class ImportGuards2 extends ValueNode { - - int do1(int a) { - return a; - } - } - - static class Imports1 { - - } - - @ExpectError("The specified import guard class 'com.oracle.truffle.api.dsl.test.ImportGuardsTest.Imports2' must be public.") - @NodeChild("a") - @ImportStatic(Imports2.class) - static class ImportGuards3 extends ValueNode { - - int do1(int a) { - return a; - } - } - - @ExpectError("The specified import guard class 'boolean' is not a declared type.") - @NodeChild("a") - @ImportStatic(boolean.class) - static class ImportGuards4 extends ValueNode { - - int do1(int a) { - return a; - } - } - - private static class Imports2 { - - } - - @ExpectError("At least import guard classes must be specified.") - @NodeChild("a") - @ImportStatic({}) - static class ImportGuards5 extends ValueNode { - - int do1(int a) { - return a; - } - } - - @Test - public void testImportGuards6() { - // should use the guar declared in the node instead of the imported one. - assertRuns(ImportGuards6Factory.getInstance(), // - array(1, 1), // - array(1, 1)); - } - - @ImportStatic(Imports0.class) - @NodeChild("a") - static class ImportGuards6 extends ValueNode { - - static boolean staticGuard(int a) { - return a == 1; - } - - @Specialization(guards = "staticGuard(a)") - int f0(int a) { - return a; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/InsertBeforeTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/InsertBeforeTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class InsertBeforeTest { - - @NodeChild("a") - static class InsertBefore1Base extends ValueNode { - - @Specialization(guards = "a == 1") - int f1(int a) { - return a; - } - - @Specialization(guards = "a == 2") - int f3(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1T1 extends InsertBefore1Base { - - @Specialization - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1T2 extends InsertBefore1Base { - - @Specialization(guards = "a == 0", insertBefore = "f1") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1T3 extends InsertBefore1Base { - - @Specialization(guards = "a == 0", insertBefore = "f3") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - @ExpectError({"Method f3(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int).", - "Method f1(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int)."}) - static class InsertBefore1T4 extends InsertBefore1Base { - - @Specialization(insertBefore = "f1") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - @ExpectError({"Method f3(int) at annotation @Specialization is erroneous: Specialization is not reachable. It is shadowed by f0(int)."}) - static class InsertBefore1T5 extends InsertBefore1Base { - - boolean g0(int a) { - return a == 0; - } - - @Specialization(insertBefore = "f3") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1T6part1 extends InsertBefore1Base { - - boolean g0(int a) { - return a == 0; - } - - @Specialization(insertBefore = "f1", guards = "a == 0") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1T6part2 extends InsertBefore1T6part1 { - - @Specialization(insertBefore = "f0", guards = "a == 3") - int f(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1Error1 extends InsertBefore1Base { - - @ExpectError("Specializations can only be inserted before specializations in superclasses.") - @Specialization(insertBefore = "f0") - int f0(int a) { - return a; - } - - } - - @NodeChild("a") - static class InsertBefore1Error2 extends InsertBefore1Base { - - @ExpectError("The referenced specialization 'asdf' could not be found.") - @Specialization(insertBefore = "asdf") - int f0(int a) { - return a; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/IntegerLiteralGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/IntegerLiteralGuardsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.IntegerLiteralGuardsTestFactory.BinaryLiteralTestFactory; -import com.oracle.truffle.api.dsl.test.IntegerLiteralGuardsTestFactory.DecimalLiteralTestFactory; -import com.oracle.truffle.api.dsl.test.IntegerLiteralGuardsTestFactory.HexLiteralTestFactory; -import com.oracle.truffle.api.dsl.test.IntegerLiteralGuardsTestFactory.OctalLiteralTestFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -@SuppressWarnings("unused") -public class IntegerLiteralGuardsTest { - - @Test - public void testDecimalLiteral() { - CallTarget root = createCallTarget(DecimalLiteralTestFactory.getInstance()); - assertEquals("do1", root.call(14)); - } - - @NodeChild - static class DecimalLiteralTest extends ValueNode { - @Specialization(guards = "value == 14") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testHexLiteral() { - CallTarget root = createCallTarget(HexLiteralTestFactory.getInstance()); - assertEquals("do1", root.call(20)); - } - - @NodeChild - static class HexLiteralTest extends ValueNode { - @Specialization(guards = "value == 0x14") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testOctalLiteral() { - CallTarget root = createCallTarget(OctalLiteralTestFactory.getInstance()); - assertEquals("do1", root.call(12)); - } - - @NodeChild - static class OctalLiteralTest extends ValueNode { - @Specialization(guards = "value == 014") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testBinaryLiteral() { - CallTarget root = createCallTarget(BinaryLiteralTestFactory.getInstance()); - assertEquals("do1", root.call(50)); - } - - @NodeChild - static class BinaryLiteralTest extends ValueNode { - @Specialization(guards = "value == 0b110010") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/LazyClassLoadingTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/LazyClassLoadingTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +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.dsl.test; - -import java.lang.reflect.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.LazyClassLoadingTestFactory.TestNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class LazyClassLoadingTest { - @Test - public void test() { - String factoryName = TestNodeFactory.class.getName(); - String nodeName = factoryName + "$" + TestNode.class.getSimpleName() + "Gen"; - Assert.assertTrue(isLoaded(factoryName)); - Assert.assertFalse(isLoaded(nodeName)); - - NodeFactory factory = TestNodeFactory.getInstance(); - Assert.assertTrue(isLoaded(factoryName)); - Assert.assertTrue(isLoaded(nodeName)); - - Assert.assertFalse(isLoaded(nodeName + "$UninitializedNode_")); - Assert.assertFalse(isLoaded(nodeName + "$BaseNode_")); - Assert.assertFalse(isLoaded(nodeName + "$IntNode_")); - Assert.assertFalse(isLoaded(nodeName + "$BooleanNode_")); - Assert.assertFalse(isLoaded(nodeName + "$PolymorphicNode_")); - - TestRootNode root = TestHelper.createRoot(factory); - - Assert.assertTrue(isLoaded(nodeName + "$UninitializedNode_")); - Assert.assertTrue(isLoaded(nodeName + "$BaseNode_")); - Assert.assertFalse(isLoaded(nodeName + "$IntNode_")); - Assert.assertFalse(isLoaded(nodeName + "$BooleanNode_")); - Assert.assertFalse(isLoaded(nodeName + "$PolymorphicNode_")); - - Assert.assertEquals(42, TestHelper.executeWith(root, 42)); - - Assert.assertTrue(isLoaded(nodeName + "$IntNode_")); - Assert.assertFalse(isLoaded(nodeName + "$BooleanNode_")); - Assert.assertFalse(isLoaded(nodeName + "$PolymorphicNode_")); - - Assert.assertEquals(true, TestHelper.executeWith(root, true)); - - Assert.assertTrue(isLoaded(nodeName + "$IntNode_")); - Assert.assertTrue(isLoaded(nodeName + "$BooleanNode_")); - Assert.assertTrue(isLoaded(nodeName + "$PolymorphicNode_")); - } - - private boolean isLoaded(String className) { - ClassLoader classLoader = getClass().getClassLoader(); - Method m; - try { - m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); - m.setAccessible(true); - return m.invoke(classLoader, className) != null; - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - @NodeChild("a") - abstract static class TestNode extends ValueNode { - - @Specialization - int doInt(int a) { - return a; - } - - @Specialization - boolean doBoolean(boolean a) { - return a; - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/LimitTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/LimitTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.LimitTestFactory.ConstantLimitTestFactory; -import com.oracle.truffle.api.dsl.test.LimitTestFactory.DefaultLimit3TestFactory; -import com.oracle.truffle.api.dsl.test.LimitTestFactory.LocalLimitTestFactory; -import com.oracle.truffle.api.dsl.test.LimitTestFactory.MethodLimitTestFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -@SuppressWarnings("unused") -public class LimitTest { - - @Test - public void testDefaultLimit3() { - CallTarget root = createCallTarget(DefaultLimit3TestFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - assertEquals(44, root.call(44)); - try { - root.call(45); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class DefaultLimit3Test extends ValueNode { - @Specialization(guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - } - - @Test - public void testConstantLimit() { - CallTarget root = createCallTarget(ConstantLimitTestFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - try { - root.call(44); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class ConstantLimitTest extends ValueNode { - - public static final int LIMIT = 2; - - @Specialization(limit = "LIMIT", guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - } - - @Test - public void testLocalLimit() { - CallTarget root = createCallTarget(LocalLimitTestFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - try { - root.call(44); - fail(); - } catch (UnsupportedSpecializationException e) { - } - } - - @NodeChild - static class LocalLimitTest extends ValueNode { - - protected int localLimit = 2; - - @Specialization(limit = "localLimit", guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - } - - @Test - public void testMethodLimit() { - MethodLimitTest.invocations = 0; - CallTarget root = createCallTarget(MethodLimitTestFactory.getInstance()); - assertEquals(42, root.call(42)); - assertEquals(43, root.call(43)); - try { - root.call(44); - fail(); - } catch (UnsupportedSpecializationException e) { - } - assertEquals(3, MethodLimitTest.invocations); - } - - @NodeChild - static class MethodLimitTest extends ValueNode { - - static int invocations = 0; - - @Specialization(limit = "calculateLimitFor(cachedValue, invocations)", guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return cachedValue; - } - - int calculateLimitFor(int cachedValue, int boundField) { - invocations = boundField + 1; - return 2; - } - - } - - @NodeChild - static class LimitErrorTest1 extends ValueNode { - @ExpectError("The limit expression has no effect.%") - @Specialization(limit = "4") - static int do1(int value) { - return value; - } - } - - @NodeChild - static class LimitErrorTest2 extends ValueNode { - public static final Object CONSTANT = new Object(); - - @ExpectError("Incompatible return type Object. Limit expressions must return int.") - @Specialization(limit = "CONSTANT", guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return value; - } - } - - @NodeChild - static class LimitErrorTest3 extends ValueNode { - - public static final Object CONSTANT = new Object(); - - @ExpectError("Limit expressions must not bind dynamic parameter values.") - @Specialization(limit = "value", guards = "value == cachedValue") - static int do1(int value, @Cached("value") int cachedValue) { - return value; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import java.util.*; -import java.util.concurrent.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestCachedNodeFactory; -import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; - -public class MergeSpecializationsTest { - - private static final int THREADS = 50; - - @NodeChild - @SuppressWarnings("unused") - abstract static class TestNode extends ValueNode { - - @Specialization - int s1(int a) { - return 1; - } - - @Specialization - int s2(long a) { - return 2; - } - - @Specialization - int s3(double a) { - return 3; - } - } - - @NodeChild - @SuppressWarnings("unused") - abstract static class TestCachedNode extends ValueNode { - - @Specialization(guards = "a == cachedA", limit = "3") - int s1(int a, @Cached("a") int cachedA) { - return 1; - } - - @Specialization - int s2(long a) { - return 2; - } - - @Specialization - int s3(double a) { - return 3; - } - } - - @Test - public void testMultithreadedMergeInOrder() { - for (int i = 0; i < 100; i++) { - multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); - } - } - - @Test - public void testMultithreadedMergeReverse() { - for (int i = 0; i < 100; i++) { - multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1.0, 1L << 32, 1), 3, 2, 1); - } - } - - @Test - public void testMultithreadedMergeCachedInOrder() { - for (int i = 0; i < 100; i++) { - multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); - } - } - - @Test - public void testMultithreadedMergeCachedTwoEntries() { - for (int i = 0; i < 100; i++) { - multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 1.0), 1, 1, 3); - } - } - - @Test - public void testMultithreadedMergeCachedThreeEntries() { - for (int i = 0; i < 100; i++) { - multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 3), 1, 1, 1); - } - } - - private static void multithreadedMerge(NodeFactory factory, final Executions executions, int... order) { - assertEquals(3, order.length); - final TestRootNode node = createRoot(factory); - - final CountDownLatch threadsStarted = new CountDownLatch(THREADS); - - final CountDownLatch beforeFirst = new CountDownLatch(1); - final CountDownLatch executedFirst = new CountDownLatch(THREADS); - - final CountDownLatch beforeSecond = new CountDownLatch(1); - final CountDownLatch executedSecond = new CountDownLatch(THREADS); - - final CountDownLatch beforeThird = new CountDownLatch(1); - final CountDownLatch executedThird = new CountDownLatch(THREADS); - - Thread[] threads = new Thread[THREADS]; - for (int i = 0; i < threads.length; i++) { - threads[i] = new Thread(new Runnable() { - public void run() { - threadsStarted.countDown(); - - MergeSpecializationsTest.await(beforeFirst); - executeWith(node, executions.firstValue); - executedFirst.countDown(); - - MergeSpecializationsTest.await(beforeSecond); - executeWith(node, executions.secondValue); - executedSecond.countDown(); - - MergeSpecializationsTest.await(beforeThird); - executeWith(node, executions.thirdValue); - executedThird.countDown(); - } - }); - threads[i].start(); - } - - final SpecializedNode gen = (SpecializedNode) node.getNode(); - - final SpecializationNode start0 = gen.getSpecializationNode(); - assertEquals("UninitializedNode_", start0.getClass().getSimpleName()); - - await(threadsStarted); - beforeFirst.countDown(); - await(executedFirst); - - final SpecializationNode start1 = gen.getSpecializationNode(); - assertEquals("S" + order[0] + "Node_", start1.getClass().getSimpleName()); - assertEquals("UninitializedNode_", nthChild(1, start1).getClass().getSimpleName()); - - beforeSecond.countDown(); - await(executedSecond); - - final SpecializationNode start2 = gen.getSpecializationNode(); - Arrays.sort(order, 0, 2); - assertEquals("PolymorphicNode_", start2.getClass().getSimpleName()); - assertEquals("S" + order[0] + "Node_", nthChild(1, start2).getClass().getSimpleName()); - assertEquals("S" + order[1] + "Node_", nthChild(2, start2).getClass().getSimpleName()); - assertEquals("UninitializedNode_", nthChild(3, start2).getClass().getSimpleName()); - - beforeThird.countDown(); - await(executedThird); - - final SpecializationNode start3 = gen.getSpecializationNode(); - Arrays.sort(order); - assertEquals("PolymorphicNode_", start3.getClass().getSimpleName()); - assertEquals("S" + order[0] + "Node_", nthChild(1, start3).getClass().getSimpleName()); - assertEquals("S" + order[1] + "Node_", nthChild(2, start3).getClass().getSimpleName()); - assertEquals("S" + order[2] + "Node_", nthChild(3, start3).getClass().getSimpleName()); - assertEquals("UninitializedNode_", nthChild(4, start3).getClass().getSimpleName()); - - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - fail("interrupted"); - } - } - } - - private static class Executions { - public final Object firstValue; - public final Object secondValue; - public final Object thirdValue; - - public Executions(Object firstValue, Object secondValue, Object thirdValue) { - this.firstValue = firstValue; - this.secondValue = secondValue; - this.thirdValue = thirdValue; - } - } - - private static void await(final CountDownLatch latch) { - try { - latch.await(); - } catch (InterruptedException e) { - fail("interrupted"); - } - } - - private static Node firstChild(Node node) { - return node.getChildren().iterator().next(); - } - - private static Node nthChild(int n, Node node) { - if (n == 0) { - return node; - } else { - return nthChild(n - 1, firstChild(node)); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,609 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardCompareWithFieldTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardComplexTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualByteIntTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualIntLongTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualLongIntTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualShortIntTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardEqualTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardFieldTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardGreaterEqualTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardGreaterTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardLessEqualTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardLessTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMethodTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMultipleAndMethodTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardMultipleOrMethodTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardNotTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardOrTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardStaticFieldTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardStaticFinalFieldCompareTestFactory; -import com.oracle.truffle.api.dsl.test.MethodGuardsTestFactory.GuardUnboundMethodTestFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -@SuppressWarnings("unused") -public class MethodGuardsTest { - - @Test - public void testGuardEqual() { - CallTarget root = createCallTarget(GuardEqualTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(1)); - } - - @NodeChild - static class GuardEqualTest extends ValueNode { - @Specialization(guards = "value == 1") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardEqualIntLong() { - CallTarget root = createCallTarget(GuardEqualIntLongTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(1)); - } - - @NodeChild - static class GuardEqualIntLongTest extends ValueNode { - @Specialization(guards = "1 == value") - static String do1(long value) { - return "do1"; - } - - @Specialization - static String do2(long value) { - return "do2"; - } - } - - @Test - public void testGuardEqualByteInt() { - CallTarget root = createCallTarget(GuardEqualByteIntTestFactory.getInstance()); - assertEquals("do1", root.call((byte) 1)); - assertEquals("do2", root.call((byte) 2)); - assertEquals("do1", root.call((byte) 1)); - } - - @NodeChild - static class GuardEqualByteIntTest extends ValueNode { - @Specialization(guards = "value == 1") - static String do1(byte value) { - return "do1"; - } - - @Specialization - static String do2(byte value) { - return "do2"; - } - } - - @Test - public void testGuardEqualShortInt() { - CallTarget root = createCallTarget(GuardEqualShortIntTestFactory.getInstance()); - assertEquals("do1", root.call((short) 1)); - assertEquals("do2", root.call((short) 2)); - assertEquals("do1", root.call((short) 1)); - } - - @NodeChild - static class GuardEqualShortIntTest extends ValueNode { - @Specialization(guards = "value == 1") - static String do1(short value) { - return "do1"; - } - - @Specialization - static String do2(short value) { - return "do2"; - } - } - - @Test - public void testGuardEqualLongInt() { - CallTarget root = createCallTarget(GuardEqualLongIntTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(1)); - } - - @NodeChild - static class GuardEqualLongIntTest extends ValueNode { - @Specialization(guards = "value == 1") - static String do1(long value) { - return "do1"; - } - - @Specialization - static String do2(long value) { - return "do2"; - } - } - - @Test - public void testGuardLessEqual() { - CallTarget root = createCallTarget(GuardLessEqualTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(0)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(0)); - } - - @NodeChild - static class GuardLessEqualTest extends ValueNode { - @Specialization(guards = "value <= 1") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardLess() { - CallTarget root = createCallTarget(GuardLessTestFactory.getInstance()); - assertEquals("do1", root.call(0)); - assertEquals("do2", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(-1)); - } - - @NodeChild - static class GuardLessTest extends ValueNode { - @Specialization(guards = "value < 1") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardGreaterEqual() { - CallTarget root = createCallTarget(GuardGreaterEqualTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(0)); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class GuardGreaterEqualTest extends ValueNode { - @Specialization(guards = "value >= 1") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardGreater() { - CallTarget root = createCallTarget(GuardGreaterTestFactory.getInstance()); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(0)); - assertEquals("do2", root.call(1)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class GuardGreaterTest extends ValueNode { - @Specialization(guards = "value > 1") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardOr() { - CallTarget root = createCallTarget(GuardOrTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(0)); - assertEquals("do2", root.call(2)); - assertEquals("do2", root.call(-1)); - } - - @NodeChild - static class GuardOrTest extends ValueNode { - @Specialization(guards = "value == 1 || value == 0") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardNot() { - CallTarget root = createCallTarget(GuardNotTestFactory.getInstance()); - assertEquals("do1", root.call(0)); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(1)); - assertEquals("do1", root.call(0)); - } - - @NodeChild - static class GuardNotTest extends ValueNode { - @Specialization(guards = "!(value == 1)") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardField() { - CallTarget root = createCallTarget(GuardFieldTestFactory.getInstance()); - GuardFieldTest node = getNode(root); - node.field = true; - assertEquals("do1", root.call(0)); - assertEquals("do1", root.call(2)); - - node.field = false; - try { - root.call(2); - fail("expected Assertion failed"); - } catch (AssertionError e) { - } - } - - @NodeChild - static class GuardFieldTest extends ValueNode { - - boolean field; - - @Specialization(guards = "field") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardCompareWithField() { - CallTarget root = createCallTarget(GuardCompareWithFieldTestFactory.getInstance()); - GuardCompareWithFieldTest node = getNode(root); - node.field = 1; - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - - node.field = 2; - assertEquals("do2", root.call(1)); - assertEquals("do1", root.call(2)); - } - - @NodeChild - static class GuardCompareWithFieldTest extends ValueNode { - - int field; - - @Specialization(guards = "value == field") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardStaticField() { - CallTarget root = createCallTarget(GuardStaticFieldTestFactory.getInstance()); - GuardStaticFieldTest.field = true; - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(2)); - GuardStaticFieldTest.field = false; - try { - root.call(2); - fail("expected Assertion failed"); - } catch (AssertionError e) { - } - } - - @NodeChild - static class GuardStaticFieldTest extends ValueNode { - - static boolean field; - - @Specialization(guards = "field") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardStaticFinalFieldCompare() { - CallTarget root = createCallTarget(GuardStaticFinalFieldCompareTestFactory.getInstance()); - GuardStaticFieldTest.field = true; - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - } - - @NodeChild - static class GuardStaticFinalFieldCompareTest extends ValueNode { - - protected static final int FIELD = 1; - - @Specialization(guards = "value == FIELD") - static String do1(int value) { - return "do1"; - } - - @Specialization(guards = "value != FIELD") - static String do2(int value) { - return "do2"; - } - } - - @Test - public void testGuardMethod() { - CallTarget root = createCallTarget(GuardMethodTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class GuardMethodTest extends ValueNode { - - @Specialization(guards = "method(value)") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - boolean method(int value) { - return value == 1; - } - } - - @Test - public void testGuardUnboundMethodField() { - CallTarget root = createCallTarget(GuardUnboundMethodTestFactory.getInstance()); - GuardUnboundMethodTest node = getNode(root); - node.hiddenValue = true; - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(2)); - node.hiddenValue = false; - try { - root.call(2); - fail("expected Assertion failed"); - } catch (AssertionError e) { - } - } - - @NodeChild - static class GuardUnboundMethodTest extends ValueNode { - - private boolean hiddenValue; - - @Specialization(guards = "method()") - static String do1(int value) { - return "do1"; - } - - boolean method() { - return hiddenValue; - } - } - - @Test - public void testStaticGuardMethod() { - CallTarget root = createCallTarget(GuardMethodTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(2)); - assertEquals("do1", root.call(1)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class StaticGuardMethodTest extends ValueNode { - - @Specialization(guards = "method(value)") - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - static boolean method(int value) { - return value == 1; - } - } - - @Test - public void testMultipleGuardAndMethod() { - CallTarget root = createCallTarget(GuardMultipleAndMethodTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(3)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class GuardMultipleAndMethodTest extends ValueNode { - - @Specialization(guards = {"method1(value)", "method2(value)"}) - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - boolean method1(int value) { - return value >= 1; - } - - boolean method2(int value) { - return value <= 2; - } - } - - @Test - public void testMultipleGuardOrMethod() { - CallTarget root = createCallTarget(GuardMultipleOrMethodTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(3)); - assertEquals("do2", root.call(0)); - } - - @NodeChild - static class GuardMultipleOrMethodTest extends ValueNode { - - @Specialization(guards = {"method1(value) || method2(value)"}) - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - boolean method1(int value) { - return value == 1; - } - - boolean method2(int value) { - return value == 2; - } - } - - @Test - public void testComplexGuard() { - CallTarget root = createCallTarget(GuardComplexTestFactory.getInstance()); - assertEquals("do1", root.call(1)); - assertEquals("do1", root.call(2)); - assertEquals("do2", root.call(3)); - assertEquals("do1", root.call(0)); - } - - @NodeChild - static class GuardComplexTest extends ValueNode { - - int field1 = 1; - static int field2 = 2; - - @Specialization(guards = {"method2(method1(field1 == 1), value <= 2)", "field2 == 2"}) - static String do1(int value) { - return "do1"; - } - - @Specialization - static String do2(int value) { - return "do2"; - } - - static boolean method1(boolean value) { - return value; - } - - boolean method2(boolean value1, boolean value2) { - return value1 && value2; - } - } - - @NodeChild - static class ErrorGuardNotTest extends ValueNode { - @ExpectError("Error parsing expression '!value == 1': The operator ! is undefined for the argument type int.") - @Specialization(guards = "!value == 1") - static String do1(int value) { - return "do1"; - } - } - - @NodeChild - static class ErrorIncompatibleReturnTypeTest extends ValueNode { - - @ExpectError("Incompatible return type int. Guards must return boolean.") - @Specialization(guards = "1") - static String do1(int value) { - return "do1"; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsWithArgumentsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MethodGuardsWithArgumentsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,265 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArguments0Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArguments1Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArgumentsDouble0Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArgumentsDouble1Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArgumentsDouble2Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArgumentsDouble3Factory; -import com.oracle.truffle.api.dsl.test.MethodGuardsWithArgumentsTestFactory.MArgumentsSingle2Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class MethodGuardsWithArgumentsTest { - - @Test - public void testMArguments0() { - TestRootNode root = createRoot(MArguments0Factory.getInstance()); - Assert.assertEquals(42, executeWith(root)); - } - - abstract static class MArguments0 extends ValueNode { - - static boolean guard() { - return true; - } - - @Specialization(guards = "guard()") - int do1() { - return 42; - } - } - - @Test - public void testMArguments1() { - TestRootNode root = createRoot(MArguments1Factory.getInstance()); - Assert.assertEquals(42, executeWith(root)); - } - - abstract static class MArguments1 extends ValueNode { - - static boolean guard() { - return true; - } - - @Specialization(guards = "guard()") - int do1() { - return 42; - } - } - - @Test - public void testMArgumentsSingle0() { - TestRootNode root = createRoot(MArguments1Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("a") - abstract static class MArgumentsSingle0 extends ValueNode { - - static boolean guard() { - return true; - } - - @Specialization(guards = "guard()") - int do1(int a) { - return a; - } - } - - @Test - public void testMArgumentsSingle1() { - TestRootNode root = createRoot(MArguments1Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("a") - abstract static class MArgumentsSingle1 extends ValueNode { - - static boolean guard(int a) { - return a == 42; - } - - @Specialization(guards = "guard(a)") - int do1(int a) { - return a; - } - } - - @Test - public void testMArgumentsSingle2() { - TestRootNode root = createRoot(MArgumentsSingle2Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42)); - } - - @NodeChild("a") - abstract static class MArgumentsSingle2 extends ValueNode { - - static boolean guard(int a1, int a2) { - return a1 == 42 && a2 == 42; - } - - @Specialization(guards = "guard(a,a)") - int do1(int a) { - return a; - } - } - - @Test - public void testMArgumentsDouble0() { - TestRootNode root = createRoot(MArgumentsDouble0Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42, 0)); - } - - @NodeChild("a") - abstract static class MArgumentsDouble0 extends ValueNode { - - static boolean guard(int a1, Object a2) { - return a1 == 42 && a2.equals(new Integer(42)); - } - - @Specialization(guards = "guard(a,a)") - int do1(int a) { - return a; - } - } - - @Test - public void testMArgumentsDouble1() { - TestRootNode root = createRoot(MArgumentsDouble1Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42, 41)); - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class MArgumentsDouble1 extends ValueNode { - - static boolean guard(int a1, double a2) { - return a1 == 42 && a2 == 41; - } - - @Specialization(guards = "guard(a,b)") - int do1(int a, @SuppressWarnings("unused") double b) { - return a; - } - } - - @Test - public void testMArgumentsDouble2() { - TestRootNode root = createRoot(MArgumentsDouble2Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42, 41.0)); - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class MArgumentsDouble2 extends ValueNode { - - static boolean guard(double a1, int a2) { - return a1 == 41 && a2 == 42; - } - - @Specialization(guards = "guard(b,a)") - int do1(int a, @SuppressWarnings("unused") double b) { - return a; - } - } - - @Test - public void testMArgumentsDouble3() { - TestRootNode root = createRoot(MArgumentsDouble3Factory.getInstance()); - Assert.assertEquals(42, executeWith(root, 42, 41.0)); - } - - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class MArgumentsDouble3 extends ValueNode { - - static boolean guard(Object a1, double a2) { - return new Double(41.0).equals(a1) && a2 == 41; - } - - @Specialization(guards = "guard(b,b)") - int do1(int a, @SuppressWarnings("unused") double b) { - return a; - } - } - - abstract static class MArgumentsError0 extends ValueNode { - - static boolean guard() { - return true; - } - - @ExpectError("Error parsing expression 'guard(': -- line 1 col 7: \")\" expected%") - @Specialization(guards = "guard(") - int do1() { - return 42; - } - } - - abstract static class MArgumentsError1 extends ValueNode { - - static boolean guard() { - return true; - } - - @ExpectError("Error parsing expression 'guard)': -- line 1 col 6: EOF expected%") - @Specialization(guards = "guard)") - int do1() { - return 42; - } - - } - - abstract static class MArgumentsError2 extends ValueNode { - - static boolean guard() { - return true; - } - - @ExpectError("Error parsing expression 'guard(a)': a cannot be resolved.") - @Specialization(guards = "guard(a)") - int do1() { - return 42; - } - } - - @NodeChild("b") - abstract static class MArgumentsError3 extends ValueNode { - - static boolean guard() { - return true; - } - - @ExpectError("Error parsing expression 'guard(a)': a cannot be resolved.") - @Specialization(guards = "guard(a)") - int do1(int b) { - return b; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NameDuplicationTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NameDuplicationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class NameDuplicationTest { - - @NodeChild - abstract static class Test0 extends ValueNode { - - @Specialization - int base(int a) { - return a; - } - - } - - @NodeChild - abstract static class Test1 extends ValueNode { - - @Specialization - int generic(int a) { - return a; - } - - } - - @NodeChild - abstract static class Test2 extends ValueNode { - - @Specialization - int polymorphic(int a) { - return a; - } - - } - - @NodeChild - abstract static class Test3 extends ValueNode { - - @Specialization - int uninitialized(int a) { - return a; - } - - } - - abstract static class AddNode extends ValueNode { - - @Specialization - int add() { - return 0; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NegatedGuardsTestFactory.NegatedGuardNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class NegatedGuardsTest { - - @Test - public void testGuardGlobal() { - TestRootNode root = createRoot(NegatedGuardNodeFactory.getInstance()); - Assert.assertEquals(42, executeWith(root)); - } - - abstract static class NegatedGuardNode extends ValueNode { - - static boolean guard() { - return true; - } - - @Specialization(guards = "!guard()") - int do1() { - throw new AssertionError(); - } - - @Specialization - int do2() { - return 42; // the generic answer to all questions - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NoTypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NoTypeSystemTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +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.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.JustFrameTestNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.NoParameterTestNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.ObjectInterfaceNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.ObjectPrimitiveTestNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.ObjectStringTestNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.PrimitiveTestNodeGen; -import com.oracle.truffle.api.dsl.test.NoTypeSystemTestFactory.TypesNotInTypeSystemTestNodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public class NoTypeSystemTest { - - abstract static class DummyChild extends Node { - abstract Object execute(); - } - - abstract static class NoParameterTestNode extends Node { - abstract void execute(); - - @Specialization - void s1() { - } - } - - @Test - public void testNoParameter() { - NoParameterTestNodeGen.create().execute(); - } - - abstract static class JustFrameTestNode extends Node { - - abstract void execute(VirtualFrame frames); - - @Specialization - void s1(@SuppressWarnings("unused") VirtualFrame frame) { - } - } - - @Test - public void testJustFrame() { - JustFrameTestNodeGen.create().execute(null); - } - - abstract static class PrimitiveTestNode extends Node { - - abstract int execute(int primitive); - - @Specialization - int test(int primitive) { - return primitive; - } - - } - - @Test - public void testPrimitive() { - Assert.assertEquals(42, PrimitiveTestNodeGen.create().execute(42)); - } - - abstract static class ObjectInterfaceNode extends Node { - - abstract CharSequence execute(Object operand); - - @Specialization - CharSequence s1(CharSequence operandSpecial) { - return operandSpecial; - } - } - - @Test - public void testObjectInterface() { - Assert.assertEquals("42", ObjectInterfaceNodeGen.create().execute("42")); - } - - abstract static class ObjectPrimitiveTestNode extends Node { - - abstract int execute(Object primitive); - - @Specialization - int s1(int primitive) { - return primitive; - } - - } - - @Test - public void testObjectPrimitiveTest() { - Assert.assertEquals(42, ObjectPrimitiveTestNodeGen.create().execute(42)); - } - - abstract static class ObjectStringTestNode extends Node { - - abstract String execute(Object operand); - - @Specialization - String s1(String operand) { - return operand; - } - } - - @Test - public void testObjectStringTest() { - Assert.assertEquals("42", ObjectStringTestNodeGen.create().execute("42")); - } - - abstract static class TypesNotInTypeSystemTest extends Node { - - abstract Object execute(Object primitive); - - abstract int executeInt(Object primitive) throws UnexpectedResultException; - - abstract double executeDouble(Object primitive) throws UnexpectedResultException; - - abstract String executeString(Object primitive) throws UnexpectedResultException; - - abstract int[] executeIntArray(Object primitive) throws UnexpectedResultException; - - abstract void executeVoid(Object primitive); - - abstract void executeChar(Object primitive); - - abstract int executeInt(int primitive) throws UnexpectedResultException; - - abstract double executeDouble(double primitive) throws UnexpectedResultException; - - abstract String executeString(String primitive) throws UnexpectedResultException; - - abstract int[] executeIntArray(int[] primitive) throws UnexpectedResultException; - - abstract void executeChar(char primitive); - - @Specialization - int s1(int primitive) { - return primitive; - } - - @Specialization - double s2(double primitive) { - return (int) primitive; - } - - @Specialization - String s3(String object) { - return object; - } - - @Specialization - int[] s4(int[] object) { - return object; - } - - @Specialization - void s5(@SuppressWarnings("unused") char object) { - } - - } - - @Test - public void testTypesNotInTypeSystem() throws UnexpectedResultException { - int[] someArray = {1, 2, 3}; - Assert.assertEquals(42, createTypesNotInTypeSystem().execute(42)); - Assert.assertEquals(42d, createTypesNotInTypeSystem().execute(42d)); - Assert.assertEquals(someArray, createTypesNotInTypeSystem().execute(someArray)); - Assert.assertNull(createTypesNotInTypeSystem().execute((char) 42)); - - Assert.assertEquals(42, createTypesNotInTypeSystem().executeInt((Object) 42)); - Assert.assertEquals(42d, createTypesNotInTypeSystem().executeDouble((Object) 42d), 0d); - Assert.assertEquals(someArray, createTypesNotInTypeSystem().executeIntArray((Object) someArray)); - createTypesNotInTypeSystem().executeChar((Object) (char) 42); - - Assert.assertEquals(42, createTypesNotInTypeSystem().executeInt(42)); - Assert.assertEquals(42d, createTypesNotInTypeSystem().executeDouble(42d), 0d); - Assert.assertEquals(someArray, createTypesNotInTypeSystem().executeIntArray(someArray)); - createTypesNotInTypeSystem().executeChar((char) 42); - - try { - createTypesNotInTypeSystem().executeInt("a"); - Assert.fail(); - } catch (UnexpectedResultException e) { - } - - try { - createTypesNotInTypeSystem().executeDouble("a"); - Assert.fail(); - } catch (UnexpectedResultException e) { - } - - try { - createTypesNotInTypeSystem().executeIntArray("a"); - Assert.fail(); - } catch (UnexpectedResultException e) { - } - - createTypesNotInTypeSystem().executeChar("a"); - - } - - private static TypesNotInTypeSystemTest createTypesNotInTypeSystem() { - return TestHelper.createRoot(TypesNotInTypeSystemTestNodeGen.create()); - } - - abstract static class ErrorImpossibleTypes1 extends Node { - - abstract int execute(int primitive); - - @Specialization - int test(int primitive) { - return primitive; - } - - @ExpectError("The provided return type \"Object\" does not match expected return type \"int\".%") - @Specialization - Object s2(int arg0) { - return arg0; - } - } - - abstract static class ErrorImpossibleTypes2 extends Node { - - abstract int execute(int primitive); - - @Specialization - int test(int primitive) { - return primitive; - } - - @ExpectError("Method signature (Object) does not match to the expected signature: %") - @Specialization - int s2(Object arg0) { - return (int) arg0; - } - } - - @ExpectError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size 1: [execute()].") - abstract static class ErrorMissingNodeChild1 extends Node { - - abstract int execute(); - - @Specialization - int s1(int arg0) { - return arg0; - } - } - - @ExpectError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size 2: [execute(int)].") - @NodeChild(type = DummyChild.class) - abstract static class ErrorMissingNodeChild2 extends Node { - - abstract int execute(int arg0); - - @Specialization - int s1(int arg0, int arg1) { - return arg0 + arg1; - } - } - - @ExpectError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size 1: [execute()].") - abstract static class ErrorMissingNodeChild3 extends Node { - - abstract int execute(); - - abstract int execute(int arg0); - - @Specialization - int s1(int arg0) { - return arg0; - } - - } - - @ExpectError("Unnecessary @NodeChild declaration. All evaluated child values are provided as parameters in execute methods.") - @NodeChild(type = DummyChild.class) - abstract static class ErrorAdditionalNodeChild1 extends Node { - - abstract int execute(int arg0); - - @Specialization - int s1(int arg0) { - return arg0; - } - } - - @NodeChild(type = DummyChild.class) - @ExpectError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size 2: [execute(int)].") - abstract static class ErrorAdditionalNodeChild2 extends Node { - - abstract int execute(int arg0); - - @Specialization - int s1(int arg0, int arg1) { - return arg0 + arg1; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeChildNoNameTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeChildNoNameTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NodeChildNoNameTestFactory.OneArgNoNameFactory; -import com.oracle.truffle.api.dsl.test.NodeChildNoNameTestFactory.ThreeArgsNoNameFactory; -import com.oracle.truffle.api.dsl.test.NodeChildNoNameTestFactory.TwoArgsNoNameFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; - -public class NodeChildNoNameTest { - - @Test - public void testOneArg() { - ValueNode node = new ConstantNode(); - OneArgNoName arg = OneArgNoNameFactory.create(node); - Assert.assertEquals(node, arg.getChild0()); - Assert.assertEquals(43, TestHelper.createCallTarget(arg).call()); - } - - @Test - public void testTwoArg() { - ValueNode node1 = new ConstantNode(); - ValueNode node2 = new ConstantNode(); - TwoArgsNoName arg = TwoArgsNoNameFactory.create(node1, node2); - Assert.assertEquals(node1, arg.getChild0()); - Assert.assertEquals(node2, arg.getChild1()); - Assert.assertEquals(84, TestHelper.createCallTarget(arg).call()); - } - - @Test - public void testThreeArg() { - ValueNode node1 = new ConstantNode(); - ValueNode node2 = new ConstantNode(); - ValueNode node3 = new ConstantNode(); - ThreeArgsNoName arg = ThreeArgsNoNameFactory.create(node1, node2, node3); - Assert.assertEquals(node1, arg.getChild0()); - Assert.assertEquals(node2, arg.getChild1()); - Assert.assertEquals(node3, arg.getChild2()); - Assert.assertEquals(126, TestHelper.createCallTarget(arg).call()); - } - - private static class ConstantNode extends ValueNode { - - @Override - public Object execute(VirtualFrame frame) { - return 42; - } - } - - @NodeChild - abstract static class OneArgNoName extends ValueNode { - - public abstract ValueNode getChild0(); - - @Specialization - int doIt(int exp) { - return exp + 1; - } - - } - - @NodeChildren({@NodeChild, @NodeChild}) - abstract static class TwoArgsNoName extends ValueNode { - - public abstract ValueNode getChild0(); - - public abstract ValueNode getChild1(); - - @Specialization - int doIt(int exp0, int exp1) { - return exp0 + exp1; - } - } - - @NodeChildren({@NodeChild, @NodeChild, @NodeChild}) - abstract static class ThreeArgsNoName extends ValueNode { - - public abstract ValueNode getChild0(); - - public abstract ValueNode getChild1(); - - public abstract ValueNode getChild2(); - - @Specialization - int doIt(int exp0, int exp1, int exp2) { - return exp0 + exp1 + exp2; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeChildTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeChildTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.IntFieldTestNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class NodeChildTest { - - @Test - public void testIntField() { - assertEquals(42, createCallTarget(IntFieldTestNodeFactory.create(42)).call()); - } - - @NodeChild("child0") - abstract static class Base0Node extends ValueNode { - - } - - @NodeChild(value = "child1", type = ValueNode.class) - abstract static class Child0Node extends Base0Node { - - @Specialization - int intField(int child0, int child1) { - return child0 + child1; - } - } - - @NodeChildren({@NodeChild("child0")}) - abstract static class Base1Node extends ValueNode { - - } - - @NodeChildren({@NodeChild(value = "child1", type = ValueNode.class)}) - abstract static class Child1Node extends Base1Node { - - @Specialization - int intField(int child0, int child1) { - return child0 + child1; - } - } - - @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) - abstract static class Base2Node extends ValueNode { - - } - - @ExpectError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size 3:%") - @NodeChildren({@NodeChild(value = "child2", type = ValueNode.class)}) - abstract static class Child2Node extends Base1Node { - - @ExpectError("Method signature (int, int, int) does not match to the expected signature:%") - @Specialization - int intField(int child0, int child1, int child2) { - return child0 + child1 + child2; - } - } - - @NodeChildren({@NodeChild(value = "receiver", type = ValueNode.class), @NodeChild(value = "arguments", type = ValueNode[].class)}) - abstract static class BaseNode extends ValueNode { - public abstract ValueNode getReceiver(); - - public abstract ValueNode[] getArguments(); - } - - abstract static class UnaryNode extends BaseNode { - @Specialization - public int doIt(int value) { - return value; - } - } - - abstract static class BinaryNode extends BaseNode { - @Specialization - public int doIt(int value0, int value1) { - return value0 + value1; - } - } - - abstract static class TernaryNode extends BaseNode { - @Specialization - public int doIt(int value0, int value1, int value2) { - return value0 + value1 + value2; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.IntFieldNoGetterTestNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.IntFieldTestNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.MultipleFieldsTestNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.ObjectContainerNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.RewriteTestNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.StringFieldTestNodeFactory; -import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.TestContainerFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class NodeFieldTest { - - @Test - public void testIntField() { - assertEquals(42, createCallTarget(IntFieldTestNodeFactory.create(42)).call()); - } - - @NodeField(name = "field", type = int.class) - abstract static class IntFieldTestNode extends ValueNode { - - public abstract int getField(); - - @Specialization - int intField() { - return getField(); - } - - } - - @Test - public void testIntFieldNoGetter() { - assertEquals(42, createCallTarget(IntFieldNoGetterTestNodeFactory.create(42)).call()); - } - - @NodeField(name = "field", type = int.class) - abstract static class IntFieldNoGetterTestNode extends ValueNode { - - @Specialization - int intField(int field) { - return field; - } - - } - - @Test - public void testMultipleFields() { - assertEquals(42, createCallTarget(MultipleFieldsTestNodeFactory.create(21, 21)).call()); - } - - @NodeFields({@NodeField(name = "field0", type = int.class), @NodeField(name = "field1", type = int.class)}) - abstract static class MultipleFieldsTestNode extends ValueNode { - - public abstract int getField0(); - - public abstract int getField1(); - - @Specialization - int intField() { - return getField0() + getField1(); - } - - } - - @Test - public void testStringField() { - assertEquals("42", createCallTarget(StringFieldTestNodeFactory.create("42")).call()); - } - - @NodeField(name = "field", type = String.class) - abstract static class StringFieldTestNode extends ValueNode { - - public abstract String getField(); - - @Specialization - String stringField() { - return getField(); - } - - } - - @Test - public void testRewrite() { - assertEquals("42", createCallTarget(RewriteTestNodeFactory.create("42")).call()); - } - - @NodeField(name = "field", type = String.class) - abstract static class RewriteTestNode extends ValueNode { - - public abstract String getField(); - - @Specialization(rewriteOn = RuntimeException.class) - String alwaysRewrite() { - throw new RuntimeException(); - } - - @Specialization(contains = "alwaysRewrite") - Object returnField() { - return getField(); - } - } - - @Test - public void testStringContainer() { - assertEquals(42, createCallTarget(TestContainerFactory.create("42")).call()); - } - - @NodeField(name = "field", type = int.class) - abstract static class IntContainerNode extends ValueNode { - - public abstract int getField(); - - } - - @NodeField(name = "anotherField", type = String.class) - abstract static class TestContainer extends ValueNode { - - @Specialization - int containerField(String field) { - return field.equals("42") ? 42 : -1; - } - - } - - @Test - public void testObjectContainer() { - assertEquals("42", createCallTarget(ObjectContainerNodeFactory.create("42")).call()); - } - - @NodeField(name = "object", type = Object.class) - abstract static class ObjectContainerNode extends ValueNode { - - public abstract Object getObject(); - - @Specialization - Object containerField() { - return getObject(); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NullLiteralGuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NullLiteralGuardsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NullLiteralGuardsTestFactory.CompareNotNullNodeFactory; -import com.oracle.truffle.api.dsl.test.NullLiteralGuardsTestFactory.CompareObjectsNullNodeFactory; -import com.oracle.truffle.api.dsl.test.NullLiteralGuardsTestFactory.CompareStringNullNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode; - -@SuppressWarnings("unused") -public class NullLiteralGuardsTest { - - @Test - public void testCompareObjectsNull() { - CallTarget root = createCallTarget(CompareObjectsNullNodeFactory.getInstance()); - assertEquals("do1", root.call((Object) null)); - assertEquals("do2", root.call("42")); - } - - abstract static class CompareObjectsNullNode extends ChildrenNode { - @Specialization(guards = "value == null") - String do1(Object value) { - return "do1"; - } - - @Specialization - String do2(Object value) { - return "do2"; - } - } - - @Test - public void testCompareStringNull() { - CallTarget root = createCallTarget(CompareStringNullNodeFactory.getInstance()); - assertEquals("do1", root.call("42")); - assertEquals("do2", root.call((Object) null)); - } - - abstract static class CompareStringNullNode extends ChildrenNode { - @Specialization(guards = "value != null") - String do1(String value) { - return "do1"; - } - - @Specialization - String do2(Object value) { - return "do2"; - } - } - - @Test - public void testCompareNotNull() { - CallTarget root = createCallTarget(CompareNotNullNodeFactory.getInstance()); - assertEquals("do1", root.call("42")); - assertEquals("do2", root.call((Object) null)); - } - - abstract static class CompareNotNullNode extends ChildrenNode { - @Specialization(guards = "value != null") - String do1(Object value) { - return "do1"; - } - - @Specialization - String do2(Object value) { - return "do2"; - } - } - - abstract static class ErrorNullIntComparison1 extends ChildrenNode { - @ExpectError("Error parsing expression 'value == null': Incompatible operand types int and null.") - @Specialization(guards = "value == null") - String do1(int value) { - return "do1"; - } - } - - abstract static class ErrorNullIntComparison2 extends ChildrenNode { - @ExpectError("Error parsing expression '1 == null': Incompatible operand types int and null.") - @Specialization(guards = "1 == null") - String do1(int value) { - return "do1"; - } - } - - abstract static class ErrorNullNullComparison extends ChildrenNode { - @ExpectError("Error parsing expression 'null == null': The operator == is undefined for the argument type(s) null null.") - @Specialization(guards = "null == null") - String do1(int value) { - return "do1"; - } - } - - abstract static class ErrorObjectVoidComparison extends ChildrenNode { - protected static void returnVoid() { - } - - @ExpectError("Error parsing expression 'value == returnVoid()': Incompatible operand types Object and void.") - @Specialization(guards = "value == returnVoid()") - String do1(Object value) { - return "do1"; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NullTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NullTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.NullTestFactory.NullTest1Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class NullTest { - - @Test - public void testGuardInvocations() { - TestRootNode root = createRoot(NullTest1Factory.getInstance()); - - assertEquals("fallback", executeWith(root, (Object) null)); - assertEquals(true, executeWith(root, true)); - assertEquals(42L, executeWith(root, 42)); - assertEquals("string", executeWith(root, "s")); - assertEquals("fallback", executeWith(root, (Object) null)); - } - - @SuppressWarnings("unused") - @NodeChild("a") - abstract static class NullTest1 extends ValueNode { - - @Specialization - long s(long a) { - return a; - } - - @Specialization - boolean s(boolean a) { - return a; - } - - @Specialization - String s(String a) { - return "string"; - } - - @Fallback - Object s(Object a) { - return "fallback"; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic1Factory; -import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic2Factory; -import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Polymorphic3Factory; -import com.oracle.truffle.api.dsl.test.TestHelper.ExecutionListener; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; - -public class PolymorphicTest { - - private static void assertParent(Node expectedParent, Node child) { - Node parent = child.getParent(); - while (parent != null && parent != expectedParent) { - parent = parent.getParent(); - } - - if (parent != expectedParent) { - assertEquals(expectedParent, parent); - } - } - - public static void assertNoDuplicates(Node node, Node... ignored) { - assertNoDuplicatesRec(new HashSet<>(Arrays.asList(ignored)), new HashSet>(), node); - } - - private static void assertNoDuplicatesRec(Set ignored, Set> seenClasses, Node current) { - if (!ignored.contains(current)) { - if (seenClasses.contains(current.getClass())) { - Assert.fail(String.format("Multiple occurences of the same class %s. %nTree: %s", current.getClass().getSimpleName(), NodeUtil.printCompactTreeToString(current.getRootNode()))); - } else { - seenClasses.add(current.getClass()); - } - } - - for (Node child : current.getChildren()) { - if (child != null) { - assertNoDuplicatesRec(ignored, seenClasses, child); - } - } - } - - @Test - public void testPolymorphic1() { - assertRuns(Polymorphic1Factory.getInstance(), // - array(42, 43, true, false, "a", "b"), // - array(42, 43, true, false, "a", "b"), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - Polymorphic1 polymorphic = ((Polymorphic1) node.getNode()); - assertParent(node.getNode(), polymorphic.getA()); - assertNoDuplicates(polymorphic, polymorphic.getA()); - if (index == 0) { - assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); - } - } - }); - } - - @NodeChild("a") - abstract static class Polymorphic1 extends ValueNode { - - public abstract ValueNode getA(); - - @Specialization - int add(int a) { - return a; - } - - @Specialization - boolean add(boolean a) { - return a; - } - - @Specialization - String add(String a) { - return a; - } - - @Fallback - String add(Object left) { - throw new AssertionError(left.toString()); - } - - } - - @Test - public void testPolymorphic2() { - assertRuns(Polymorphic2Factory.getInstance(), // - array(0, 1, 1, "1", "2", 2, 3), // - array(0, 1, 1, "1", "2", 2, 3), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - Polymorphic2 polymorphic = ((Polymorphic2) node.getNode()); - assertParent(node.getNode(), polymorphic.getA()); - assertNoDuplicates(polymorphic, polymorphic.getA()); - if (index == 0) { - assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); - } - } - }); - } - - @NodeChild("a") - abstract static class Polymorphic2 extends ValueNode { - - public abstract ValueNode getA(); - - @Specialization - String s2(String a) { - return a; - } - - @Specialization(rewriteOn = RuntimeException.class) - int s0(int a) { - if (a == 1) { - throw new RuntimeException(); - } - return a; - } - - @Specialization - int s1(int a) { - return a; - } - - } - - @Test - public void testPolymorphic3() { - assertRuns(Polymorphic3Factory.getInstance(), // - array("0", "1", 1, 1, 2, 2, 3, 3), // - array("0", "1", 1, 1, 2, 2, 3, 3), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - Polymorphic3 polymorphic = ((Polymorphic3) node.getNode()); - assertParent(node.getNode(), polymorphic.getA()); - assertNoDuplicates(polymorphic, polymorphic.getA()); - } - }); - } - - @NodeChild("a") - abstract static class Polymorphic3 extends ValueNode { - - public abstract ValueNode getA(); - - @Specialization - String s2(String a) { - return a; - } - - @Specialization(rewriteOn = RuntimeException.class) - int s0(int a) { - if (a == 1) { - throw new RuntimeException(); - } - return a; - } - - @Specialization(rewriteOn = RuntimeException.class) - int s1(int a) { - if (a == 1) { - throw new RuntimeException(); - } - return a; - } - - @Specialization - int s2(int a) { - return a; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.BinaryNodeTest.BinaryNode; -import com.oracle.truffle.api.dsl.test.PolymorphicTest2Factory.Polymorphic1Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.nodes.*; - -public class PolymorphicTest2 { - - @Test - public void testMultipleTypes() { - /* Tests the unexpected polymorphic case. */ - TestRootNode node = TestHelper.createRoot(Polymorphic1Factory.getInstance()); - assertEquals(21, executeWith(node, false, false)); - assertEquals(42, executeWith(node, 21, 21)); - assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); - } - - @SuppressWarnings("unused") - abstract static class Polymorphic1 extends BinaryNode { - - @Specialization - int add(int left, int right) { - return 42; - } - - @Specialization - int add(boolean left, boolean right) { - return 21; - } - - @Specialization - String add(boolean left, int right) { - return "(boolean,int)"; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ReachabilityTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ReachabilityTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.Abstract; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.BExtendsAbstract; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class ReachabilityTest { - - static class Reachability1 extends ValueNode { - @Specialization - int do2() { - return 2; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2().") - @Specialization - int do1() { - return 2; - } - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType1 extends ValueNode { - @Specialization - int do2(int a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(int).") - @Specialization - int do1(int a) { - return a; - } - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType2 extends ValueNode { - @Specialization - BExtendsAbstract do2(BExtendsAbstract a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(BExtendsAbstract).") - @Specialization - BExtendsAbstract do1(BExtendsAbstract a) { - return a; - } - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType3 extends ValueNode { - @Specialization - Abstract do2(Abstract a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(Abstract).") - @Specialization - BExtendsAbstract do1(BExtendsAbstract a) { - return a; - } - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType4 extends ValueNode { - - @Specialization - BExtendsAbstract do2(BExtendsAbstract a) { - return a; - } - - @Specialization - Abstract do1(Abstract a) { - return a; - } - - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType5 extends ValueNode { - - @Specialization - double do2(double a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(double).") - @Specialization - int do1(int a) { - return a; - } - - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType6 extends ValueNode { - - @Specialization - BigInteger do2(BigInteger a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(BigInteger).") - @Specialization - int do1(int a) { - return a; - } - - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType7 extends ValueNode { - - @Specialization - int do2(int a) { - return a; - } - - @Specialization - BigInteger do1(BigInteger a) { - return a; - } - - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType8 extends ValueNode { - - @Specialization - int do2(int a) { - return a; - } - - @Specialization - Object do1(Object a) { - return a; - } - - } - - @NodeChildren({@NodeChild("a")}) - static class ReachabilityType9 extends ValueNode { - - @Specialization - Object do2(Object a) { - return a; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2(Object).") - @Specialization - int do1(int a) { - return a; - } - } - - static class ReachabilityGuard1 extends ValueNode { - - boolean foo() { - return false; - } - - @Specialization(guards = "foo()") - int do2() { - return 1; - } - - @Specialization - int do1() { - return 2; - } - - } - - static class ReachabilityGuard2 extends ValueNode { - - boolean foo() { - return false; - } - - @Specialization - int do2() { - return 2; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2().") - @Specialization(guards = "foo()") - int do1() { - return 1; - } - - } - - static class ReachabilityGuard3 extends ValueNode { - - boolean foo() { - return false; - } - - @Specialization(guards = "foo()") - int do2() { - return 1; - } - - @Specialization - int do1() { - return 2; - } - - } - - static class ReachabilityGuard4 extends ValueNode { - - boolean foo() { - return false; - } - - @Specialization(guards = "foo()") - int do2() { - return 1; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2().") - @Specialization(guards = "foo()") - int do1() { - return 2; - } - - } - - static class ReachabilityThrowable1 extends ValueNode { - - @Specialization(rewriteOn = RuntimeException.class) - int do2() throws RuntimeException { - return 1; - } - - @Specialization - int do1() { - return 2; - } - - } - - static class ReachabilityThrowable2 extends ValueNode { - - @Specialization - int do2() { - return 1; - } - - @ExpectError("Specialization is not reachable. It is shadowed by do2().") - @Specialization(rewriteOn = RuntimeException.class) - int do1() throws RuntimeException { - return 2; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.DoubleChildNodeFactory; -import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.ShortCircuitWithImplicitCastNodeFactory; -import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.SingleChildNodeFactory; -import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.VarArgsNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class ShortCircuitTest { - - @Test - public void testSingleChild1() { - ArgumentNode arg0 = new ArgumentNode(0); - CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); - SingleChildNode.needsChild = true; - assertEquals(42, callTarget.call(new Object[]{42})); - assertEquals(1, arg0.getInvocationCount()); - } - - @Test - public void testSingleChild2() { - ArgumentNode arg0 = new ArgumentNode(0); - CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); - SingleChildNode.needsChild = false; - assertEquals(0, callTarget.call(new Object[]{42})); - assertEquals(0, arg0.getInvocationCount()); - } - - @NodeChild("child0") - abstract static class SingleChildNode extends ValueNode { - - static boolean needsChild; - - @ShortCircuit("child0") - boolean needsChild0() { - return needsChild; - } - - @Specialization - int doIt(boolean hasChild0, int child0) { - assert hasChild0 == needsChild0(); - return child0; - } - - } - - @Test - public void testDoubleChild1() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); - assertEquals(42, callTarget.call(new Object[]{41, 42})); - assertEquals(1, arg1.getInvocationCount()); - } - - @Test - public void testDoubleChild2() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); - assertEquals(0, callTarget.call(new Object[]{42, 42})); - assertEquals(0, arg1.getInvocationCount()); - } - - @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) - @SuppressWarnings("unused") - abstract static class DoubleChildNode extends ValueNode { - - @ShortCircuit("child1") - boolean needsChild1(Object leftValue) { - return leftValue.equals(41); - } - - @Specialization - int doIt(int child0, boolean hasChild1, int child1) { - return child1; - } - - } - - @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) - @SuppressWarnings("unused") - abstract static class GuardChildNode extends ValueNode { - - @ShortCircuit("child1") - boolean needsChild1(Object a) { - return a.equals(new Integer(42)); - } - - static boolean guard(int a, boolean hasB, int b) { - return false; - } - - @Specialization(guards = "guard(a, hasB, b)") - int doIt(int a, boolean hasB, int b) { - return a + b; - } - - } - - @Test - public void testVarArgs1() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); - assertEquals(42, callTarget.call(new Object[]{41, 42})); - assertEquals(1, arg1.getInvocationCount()); - } - - @Test - public void testVarArgs2() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); - assertEquals(0, callTarget.call(new Object[]{42, 42})); - assertEquals(0, arg1.getInvocationCount()); - } - - @NodeChild(value = "children", type = ValueNode[].class) - abstract static class VarArgsNode extends ValueNode { - - @ShortCircuit("children[1]") - boolean needsChild1(Object leftValue) { - return leftValue.equals(41); - } - - @Specialization - @SuppressWarnings("unused") - int doIt(int child0, boolean hasChild1, int child1) { - return child1; - } - - } - - @Test - public void testShortCircuitWithImplicitCastNode() { - ArgumentNode arg0 = new ArgumentNode(0); - ArgumentNode arg1 = new ArgumentNode(1); - CallTarget callTarget = TestHelper.createCallTarget(ShortCircuitWithImplicitCastNodeFactory.create(new ValueNode[]{arg0, arg1})); - assertEquals(42, callTarget.call(new Object[]{42, 41})); - } - - @TypeSystem(int.class) - abstract static class ShortCircuitWithImplicitCastTypes { - - @ImplicitCast - public static int doAnImplicitCast(String foo) { - return Integer.parseInt(foo); - } - - } - - @NodeChild(value = "children", type = ValueNode[].class) - @TypeSystemReference(ShortCircuitWithImplicitCastTypes.class) - abstract static class ShortCircuitWithImplicitCastNode extends ValueNode { - - @ShortCircuit("children[1]") - public boolean needsRightNode(Object left) { - return (int) left == 41; - } - - @Specialization - public int doInteger(int left, boolean needsRight, int right) { - return needsRight ? right : left; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SourceSectionTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SourceSectionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.dsl.test.SourceSectionTestFactory.SourceSection0Factory; -import com.oracle.truffle.api.dsl.test.SourceSectionTestFactory.SourceSection1Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -@RunWith(Theories.class) -public class SourceSectionTest { - - @DataPoints public static final int[] data = new int[]{1, 2, 3, 4}; - - @Theory - public void testSourceSections(int value0, int value1, int value2) { - TestRootNode root = createRoot(SourceSection0Factory.getInstance()); - SourceSection section = new NullSourceSection("a", "b"); - root.getNode().assignSourceSection(section); - expectSourceSection(root.getNode(), section); - assertThat((int) executeWith(root, value0), is(value0)); - expectSourceSection(root.getNode(), section); - assertThat((int) executeWith(root, value1), is(value1)); - expectSourceSection(root.getNode(), section); - assertThat((int) executeWith(root, value2), is(value2)); - expectSourceSection(root.getNode(), section); - } - - private static void expectSourceSection(Node root, SourceSection section) { - assertThat(root.getSourceSection(), is(sameInstance(section))); - for (Node child : root.getChildren()) { - if (child instanceof ArgumentNode || child instanceof SpecializationNode) { - continue; - } - if (child != null) { - expectSourceSection(child, section); - } - } - } - - @NodeChild("a") - static class SourceSection0 extends ValueNode { - - @Specialization(guards = "a == 1") - int do1(int a) { - return a; - } - - @Specialization(guards = "a == 2") - int do2(int a) { - return a; - } - - @Specialization(guards = "a == 3") - int do3(int a) { - return a; - } - - @Fallback - Object do4(Object a) { - return a; // the generic answer to all questions - } - } - - @Test - public void testCreateCast() { - SourceSection section = new NullSourceSection("a", "b"); - TestRootNode root = createRootPrefix(SourceSection1Factory.getInstance(), true, section); - expectSourceSection(root.getNode(), section); - assertThat((int) executeWith(root, 1), is(1)); - expectSourceSection(root.getNode(), section); - } - - @NodeChild("a") - static class SourceSection1 extends ValueNode { - - public SourceSection1(SourceSection section) { - super(section); - } - - @CreateCast("a") - public ValueNode cast(ValueNode node) { - assert getSourceSection() != null; - return node; - } - - @Specialization - int do0(int a) { - return a; - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationFallthroughTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationFallthroughTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,373 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest0Factory; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest1Factory; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest2Factory; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest3Factory; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest4Factory; -import com.oracle.truffle.api.dsl.test.SpecializationFallthroughTestFactory.FallthroughTest5Factory; -import com.oracle.truffle.api.dsl.test.TestHelper.ExecutionListener; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class SpecializationFallthroughTest { - - @Test - public void testFallthrough0() { - assertRuns(FallthroughTest0Factory.getInstance(), // - array(0, 0, 1, 2), // - array(0, 0, 1, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest0.fallthroughCount > 1) { - Assert.fail("The fallthrough case must never be triggered twice. Therfore count must be <= 1, but is not."); - } - } - }); - } - - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest0 extends ValueNode { - - static int fallthroughCount = 0; - - public FallthroughTest0() { - fallthroughCount = 0; - } - - @Specialization(rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthroughCount++; - throw new ArithmeticException(); - } - return a; - } - - @Fallback - Object doFallback(Object a) { - return a; - } - } - - /* - * Tests that the fall through is never triggered twice for monomorphic cases. - */ - @Test - public void testFallthrough1() { - assertRuns(FallthroughTest1Factory.getInstance(), // - array(0, 0, 0, 1, 2), // - array(0, 0, 0, 1, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest1.fallthroughCount > 1) { - Assert.fail("The fallthrough case must never be triggered twice. Therfore count must be <= 1, but is not."); - } - } - }); - } - - /* TODO assert falltrough do1 before do2 */ - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest1 extends ValueNode { - - static int fallthroughCount; - - public FallthroughTest1() { - fallthroughCount = 0; - } - - @Specialization(rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthroughCount++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization - int do2(int a) { - return a; - } - - } - - /* - * Tests that the fall through is never triggered twice with two falltrhoughs in one operation. - */ - @Test - public void testFallthrough2() { - assertRuns(FallthroughTest2Factory.getInstance(), // - array(0, 0, 1, 1, 2, 2), // - array(0, 0, 1, 1, 2, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest2.fallthrough1 > 1) { - Assert.fail(); - } - if (FallthroughTest2.fallthrough2 > 1) { - Assert.fail(); - } - FallthroughTest2.fallthrough1 = 0; - FallthroughTest2.fallthrough2 = 0; - } - }); - } - - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest2 extends ValueNode { - - static int fallthrough1; - static int fallthrough2; - - @Specialization(order = 1, rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthrough1++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization(order = 2, rewriteOn = ArithmeticException.class) - int do2(int a) throws ArithmeticException { - if (a == 1) { - fallthrough2++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization - int do3(int a) { - return a; - } - } - - /* - * Tests that the fall through is never triggered twice. In this case mixed fallthrough with - * normal specializations. - */ - @Test - public void testFallthrough3() { - assertRuns(FallthroughTest3Factory.getInstance(), // - array(0, 0, 1, 1, 2, 2), // - array(0, 0, 1, 1, 2, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest3.fallthrough1 > 1) { - Assert.fail(String.valueOf(FallthroughTest3.fallthrough1)); - } - FallthroughTest3.fallthrough1 = 0; - } - }); - } - - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest3 extends ValueNode { - - static int fallthrough1; - - boolean guard0(int a) { - return a == 1; - } - - @Specialization(guards = "guard0(a)") - int do2(int a) { - return a; - } - - @Specialization(rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthrough1++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization - int do3(int a) { - return a; - } - - } - - @Test - public void testFallthrough4() { - assertRuns(FallthroughTest4Factory.getInstance(), // - array(0, 0, 1, 1, 2, 2), // - array(0, 0, 1, 1, 2, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest4.fallthrough1 > 1) { - Assert.fail(String.valueOf(FallthroughTest4.fallthrough1)); - } - if (FallthroughTest4.fallthrough2 > 1) { - Assert.fail(String.valueOf(FallthroughTest4.fallthrough1)); - } - FallthroughTest4.fallthrough1 = 0; - FallthroughTest4.fallthrough2 = 0; - } - }); - } - - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest4 extends ValueNode { - - static int fallthrough1; - static int fallthrough2; - - @Specialization(order = 1, rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthrough1++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization(order = 2, rewriteOn = ArithmeticException.class) - int do2(int a) throws ArithmeticException { - if (a == 1) { - fallthrough2++; - throw new ArithmeticException(); - } - return a; - } - - @Specialization - int do3(int a) { - return a; - } - - } - - @Test - public void testFallthrough5() { - assertRuns(FallthroughTest5Factory.getInstance(), // - array(0, 0, 1, 1, 2, 2), // - array(0, 0, 1, 1, 2, 2), // - new ExecutionListener() { - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - if (!last) { - return; - } - if (FallthroughTest5.fallthrough1 > 1) { - Assert.fail(String.valueOf(FallthroughTest5.fallthrough1)); - } - FallthroughTest5.fallthrough1 = 0; - } - }); - } - - @NodeChildren({@NodeChild("a")}) - static class FallthroughTest5 extends ValueNode { - - static int fallthrough1; - - @Specialization(guards = "isDo1(a)", rewriteOn = ArithmeticException.class) - int do1(int a) throws ArithmeticException { - if (a == 0) { - fallthrough1++; - throw new ArithmeticException(); - } - return a; - } - - protected static boolean isDo1(int a) { - return a == 0 || a == 1; - } - - @Specialization(guards = "isDo1(a)") - int do2(int a) { - return a; - } - - @Specialization - int do3(int a) { - return a; - } - - } - - /* Throwing RuntimeExceptions without rewriteOn is allowed. */ - @NodeChildren({@NodeChild("a")}) - static class FallthroughExceptionType0 extends ValueNode { - - @Specialization - int do4(int a) throws RuntimeException { - return a; - } - - } - - /* Non runtime exceptions must be verified. */ - @NodeChildren({@NodeChild("a")}) - static class FallthroughExceptionType1 extends ValueNode { - - @ExpectError("A rewriteOn checked exception was specified but not thrown in the method's throws clause. The @Specialization method must specify a throws clause with the exception type 'java.lang.Throwable'.") - @Specialization(rewriteOn = Throwable.class) - int do4(int a) { - return a; - } - - } - - /* Checked exception must be verified. */ - @NodeChildren({@NodeChild("a")}) - static class FallthroughExceptionType2 extends ValueNode { - - @ExpectError("A checked exception 'java.lang.Throwable' is thrown but is not specified using the rewriteOn property. " - + "Checked exceptions that are not used for rewriting are not handled by the DSL. Use RuntimeExceptions for this purpose instead.") - @Specialization - int do4(int a) throws Throwable { - return a; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.test; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.SpecializationGroupingTestFactory.TestElseConnectionBug1Factory; -import com.oracle.truffle.api.dsl.test.SpecializationGroupingTestFactory.TestElseConnectionBug2Factory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Tests execution counts of guards. While we do not make guarantees for guard invocation except for - * their execution order our implementation reduces the calls to guards as much as possible for the - * generic case. - */ -public class SpecializationGroupingTest { - - @Test - public void testElseConnectionBug1() { - CallTarget target = TestHelper.createCallTarget(TestElseConnectionBug1Factory.create(new GenericInt())); - Assert.assertEquals(42, target.call()); - } - - @SuppressWarnings("unused") - @NodeChild(value = "genericChild", type = GenericInt.class) - public abstract static class TestElseConnectionBug1 extends ValueNode { - - @Specialization(rewriteOn = {SlowPathException.class}, guards = "isInitialized(value)") - public int do1(int value) throws SlowPathException { - throw new SlowPathException(); - } - - @Specialization(contains = "do1", guards = "isInitialized(value)") - public int do2(int value) { - return value == 42 ? value : 0; - } - - @Specialization(guards = "!isInitialized(value)") - public Object do3(int value) { - throw new AssertionError(); - } - - boolean isInitialized(int value) { - return true; - } - } - - public static final class GenericInt extends ValueNode { - - @Override - public Object execute(VirtualFrame frame) { - return executeInt(frame); - } - - @Override - public int executeInt(VirtualFrame frame) { - return 42; - } - - } - - @Test - public void testElseConnectionBug2() { - TestHelper.assertRuns(TestElseConnectionBug2Factory.getInstance(), new Object[]{42}, new Object[]{42}); - } - - @SuppressWarnings("unused") - @NodeChild - public abstract static class TestElseConnectionBug2 extends ValueNode { - - @Specialization(guards = "guard0(value)") - public int do1(int value) { - throw new AssertionError(); - } - - @Specialization(guards = "guard1(value)") - public int do2(int value) { - throw new AssertionError(); - } - - @Specialization(guards = "!guard0(value)") - public int do3(int value) { - return value; - } - - boolean guard0(int value) { - return false; - } - - boolean guard1(int value) { - return false; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +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.dsl.test; - -import static org.junit.Assert.*; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Utility class to provide some test helper functions. - */ -class TestHelper { - - // make nodes replacable - public static T createRoot(final T node) { - new RootNode() { - @Child T child = node; - - @Override - public Object execute(VirtualFrame frame) { - return null; - } - }.adoptChildren(); - return node; - } - - private static ArgumentNode[] arguments(int count) { - ArgumentNode[] nodes = new ArgumentNode[count]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = new ArgumentNode(i); - } - return nodes; - } - - static E createNode(NodeFactory factory, boolean prefixConstants, Object... constants) { - ArgumentNode[] argumentNodes = arguments(factory.getExecutionSignature().size()); - - List argumentList = new ArrayList<>(); - if (prefixConstants) { - argumentList.addAll(Arrays.asList(constants)); - } - if (ChildrenNode.class.isAssignableFrom(factory.getNodeClass())) { - argumentList.add(argumentNodes); - } else { - argumentList.addAll(Arrays.asList(argumentNodes)); - } - if (!prefixConstants) { - argumentList.addAll(Arrays.asList(constants)); - } - return factory.createNode(argumentList.toArray(new Object[argumentList.size()])); - } - - static TestRootNode createRoot(NodeFactory factory, Object... constants) { - TestRootNode rootNode = new TestRootNode<>(createNode(factory, false, constants)); - rootNode.adoptChildren(); - return rootNode; - } - - static TestRootNode createRootPrefix(NodeFactory factory, boolean prefixConstants, Object... constants) { - TestRootNode rootNode = new TestRootNode<>(createNode(factory, prefixConstants, constants)); - rootNode.adoptChildren(); - return rootNode; - } - - static CallTarget createCallTarget(ValueNode node) { - return createCallTarget(new TestRootNode<>(node)); - } - - static CallTarget createCallTarget(TestRootNode node) { - return Truffle.getRuntime().createCallTarget(node); - } - - static RootCallTarget createCallTarget(NodeFactory factory, Object... constants) { - return Truffle.getRuntime().createCallTarget(createRoot(factory, constants)); - } - - static boolean assertionsEnabled() { - boolean assertOn = false; - // *assigns* true if assertions are on. - assert (assertOn = true) == true; - return assertOn; - } - - @SuppressWarnings("unchecked") - static T getNode(CallTarget target) { - return ((TestRootNode) ((RootCallTarget) target).getRootNode()).getNode(); - } - - static Object executeWith(TestRootNode node, Object... values) { - return createCallTarget(node).call(values); - } - - static Object[] array(Object... val) { - return val; - } - - static List> permutations(List list) { - return permutations(new ArrayList(), list, new ArrayList>()); - } - - static Object[][] permutations(Object... list) { - List> permutations = permutations(Arrays.asList(list)); - - Object[][] a = new Object[permutations.size()][]; - int index = 0; - for (List p : permutations) { - a[index] = p.toArray(new Object[p.size()]); - index++; - } - - return a; - } - - static List> permutations(List prefix, List suffix, List> output) { - if (suffix.size() == 1) { - ArrayList newElement = new ArrayList<>(prefix); - newElement.addAll(suffix); - output.add(newElement); - return output; - } - - for (int i = 0; i < suffix.size(); i++) { - List newPrefix = new ArrayList<>(prefix); - newPrefix.add(suffix.get(i)); - List newSuffix = new ArrayList<>(suffix); - newSuffix.remove(i); - permutations(newPrefix, newSuffix, output); - } - - return output; - } - - static void assertRuns(NodeFactory factory, Object[] testValues, Object[] result) { - assertRuns(factory, testValues, result, null); - } - - /* Methods tests all test values in combinational order. */ - static void assertRuns(NodeFactory factory, Object[] testValues, Object[] result, ExecutionListener listener) { - // test each run by its own. - for (int i = 0; i < testValues.length; i++) { - assertValue(createRoot(factory), 0, testValues[i], result[i], listener, true); - } - - // test all combinations of the test values - List testValuesList = Arrays.asList(testValues); - List> permuts = permutations(testValuesList); - for (List list : permuts) { - TestRootNode root = createRoot(factory); - int index = 0; - for (Object object : list) { - assertValue(root, index, object, result[testValuesList.indexOf(object)], listener, index == list.size() - 1); - index++; - } - } - } - - static void assertValue(TestRootNode root, int index, Object value, Object result, ExecutionListener listener, boolean last) { - Object actualResult = null; - if (result instanceof Class && Throwable.class.isAssignableFrom((Class) result)) { - try { - if (value instanceof Object[]) { - actualResult = executeWith(root, (Object[]) value); - } else { - actualResult = executeWith(root, value); - } - fail(String.format("Exception %s expected but not occured.", result.getClass())); - } catch (Throwable e) { - actualResult = e; - if (!e.getClass().isAssignableFrom(((Class) result))) { - e.printStackTrace(); - fail(String.format("Incompatible exception class thrown. Expected %s but was %s.", result.toString(), e.getClass())); - } - } - } else if (value instanceof Object[]) { - actualResult = executeWith(root, (Object[]) value); - assertEquals(result, actualResult); - } else { - actualResult = executeWith(root, value); - assertEquals(result, actualResult); - } - if (listener != null) { - listener.afterExecution(root, index, value, result, actualResult, last); - } - } - - public static final class LogListener implements ExecutionListener { - - public void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last) { - System.out.printf("Run %3d Node:%-20s Parameters: %10s Expected: %10s Result %10s%n", index, node.getNode().getClass().getSimpleName(), value, expectedResult, actualResult); - } - - } - - interface ExecutionListener { - - void afterExecution(TestRootNode node, int index, Object value, Object expectedResult, Object actualResult, boolean last); - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestSerialization.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestSerialization.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +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.dsl.test; - -import static com.oracle.truffle.api.dsl.test.TestHelper.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TestSerializationFactory.SerializedNodeFactory; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.nodes.*; - -public class TestSerialization { - - @Test - public void testUpdateRoot() { - /* Tests the unexpected polymorphic case. */ - TestRootNode node = TestHelper.createRoot(SerializedNodeFactory.getInstance()); - assertEquals(true, executeWith(node, true)); - assertEquals(21, executeWith(node, 21)); - assertEquals("s", executeWith(node, "s")); - assertEquals(3, node.getNode().invocations); - assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); - - @SuppressWarnings("unchecked") - TestRootNode copiedNode = (TestRootNode) node.deepCopy(); - copiedNode.adoptChildren(); - assertTrue(copiedNode != node); - assertEquals(true, executeWith(copiedNode, true)); - assertEquals(21, executeWith(copiedNode, 21)); - assertEquals("s", executeWith(copiedNode, "s")); - assertEquals(6, copiedNode.getNode().invocations); - } - - @NodeChild - abstract static class SerializedNode extends ValueNode { - - int invocations; - - @Specialization - int add(int left) { - invocations++; - return left; - } - - @Specialization - boolean add(boolean left) { - invocations++; - return left; - } - - @Specialization - String add(String left) { - invocations++; - return left; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemErrorsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemErrorsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +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.dsl.test; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemErrorsTest.Types1.Type1; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; - -public class TypeSystemErrorsTest { - - @TypeSystem({int.class, boolean.class}) - public static class ErrorTypes0 { - - } - - @ExpectError("Invalid type order. The type(s) [java.lang.String] are inherited from a earlier defined type java.lang.CharSequence.") - @TypeSystem({CharSequence.class, String.class}) - public static class ErrorTypes1 { - - } - - public static class Types1 { - public static class Type1 { - } - } - - public static class Types2 { - public static class Type1 { - } - } - - // verify boxed type overlay - @ExpectError("Two types result in the same boxed name: Type1.") - @TypeSystem({Type1.class, com.oracle.truffle.api.dsl.test.TypeSystemErrorsTest.Types2.Type1.class}) - public static class ErrorTypes2 { - - } - - public static class Types3 { - public static class Object { - } - } - - // verify Object name cannot appear - @ExpectError("Two types result in the same boxed name: Object.") - @TypeSystem({com.oracle.truffle.api.dsl.test.TypeSystemErrorsTest.Types3.Object.class}) - public static class ErrorTypes3 { - } - - public static class Types4 { - public static class Integer { - } - } - - // verify int boxed name - @ExpectError("Two types result in the same boxed name: Integer.") - @TypeSystem({int.class, com.oracle.truffle.api.dsl.test.TypeSystemErrorsTest.Types4.Integer.class}) - public static class ErrorTypes4 { - } - - @TypeSystemReference(ErrorTypes0.class) - @NodeChild - @ExpectError("The @TypeSystem of the node and the @TypeSystem of the @NodeChild does not match. Types0 != SimpleTypes. ") - abstract static class ErrorNode1 extends ValueNode { - } - - @TypeSystem({int.class}) - public static class CastError1 { - @TypeCast(int.class) - @ExpectError("The provided return type \"String\" does not match expected return type \"int\".%") - public static String asInteger(Object value) { - return (String) value; - } - } - - @TypeSystem({int.class}) - public static class CastError2 { - @TypeCast(int.class) - @ExpectError("The provided return type \"boolean\" does not match expected return type \"int\".%") - public static boolean asInteger(Object value) { - return (boolean) value; - } - } - - @TypeSystem({int.class}) - public static class CastError4 { - @ExpectError("@TypeCast annotated method asInt must be public and static.") - @TypeCast(int.class) - public int asInt(Object value) { - return (int) value; - } - } - - @TypeSystem({int.class}) - public static class CastError5 { - @ExpectError("@TypeCast annotated method asInt must be public and static.") - @TypeCast(int.class) - static int asInt(Object value) { - return (int) value; - } - } - - @TypeSystem({int.class}) - public static class CheckError2 { - @ExpectError("@TypeCheck annotated method isInt must be public and static.") - @TypeCheck(int.class) - public boolean isInt(Object value) { - return value instanceof Integer; - } - } - - @TypeSystem({int.class}) - public static class CheckError3 { - @ExpectError("@TypeCheck annotated method isInt must be public and static.") - @TypeCheck(int.class) - static boolean isInt(Object value) { - return value instanceof Integer; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +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.dsl.test; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -public class TypeSystemTest { - - @TypeSystem({byte.class, short.class, int.class, long.class, double.class, boolean.class, BigInteger.class, String.class, CallTarget.class, BExtendsAbstract.class, CExtendsAbstract.class, - Abstract.class, Interface.class, Object[].class}) - @DSLOptions(useNewLayout = true) - static class SimpleTypes { - - static int intCheck; - static int intCast; - - @TypeCheck(int.class) - public static boolean isInteger(Object value) { - intCheck++; - return value instanceof Integer; - } - - @TypeCast(int.class) - public static int asInteger(Object value) { - intCast++; - return (int) value; - } - - @ImplicitCast - public static double castDouble(int value) { - return value; - } - - @ImplicitCast - public static long castLong(int value) { - return value; - } - - @ImplicitCast - public static BigInteger castBigInteger(int value) { - return BigInteger.valueOf(value); - } - - } - - @TypeSystemReference(SimpleTypes.class) - @GenerateNodeFactory - public static class ValueNode extends Node { - - public ValueNode() { - super(null); - } - - public ValueNode(SourceSection sourceSection) { - super(sourceSection); - } - - public int executeInt(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectInteger(execute(frame)); - } - - public long executeLong(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectLong(execute(frame)); - } - - public String executeString(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectString(execute(frame)); - } - - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectBoolean(execute(frame)); - } - - public Object[] executeIntArray(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectObjectArray(execute(frame)); - } - - public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectBigInteger(execute(frame)); - } - - public BExtendsAbstract executeBExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectBExtendsAbstract(execute(frame)); - } - - public CExtendsAbstract executeCExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectCExtendsAbstract(execute(frame)); - } - - public Abstract executeAbstract(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectAbstract(execute(frame)); - } - - public double executeDouble(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectDouble(execute(frame)); - } - - public Interface executeInterface(VirtualFrame frame) throws UnexpectedResultException { - return SimpleTypesGen.expectInterface(execute(frame)); - } - - public Object execute(@SuppressWarnings("unused") VirtualFrame frame) { - throw new UnsupportedOperationException(); - } - - @Override - public ValueNode copy() { - return (ValueNode) super.copy(); - } - } - - @NodeChild(value = "children", type = ValueNode[].class) - @GenerateNodeFactory - public abstract static class ChildrenNode extends ValueNode { - - } - - @TypeSystemReference(SimpleTypes.class) - public static class TestRootNode extends RootNode { - - @Child private E node; - - public TestRootNode(E node) { - super(null); - this.node = node; - } - - @Override - public Object execute(VirtualFrame frame) { - return node.execute(frame); - } - - public E getNode() { - return node; - } - } - - public static class ArgumentNode extends ValueNode { - - private int invocationCount; - final int index; - - public ArgumentNode(int index) { - this.index = index; - } - - public int getInvocationCount() { - return invocationCount; - } - - @Override - public Object execute(VirtualFrame frame) { - invocationCount++; - return frame.getArguments()[index]; - } - - @Override - public int executeInt(VirtualFrame frame) throws UnexpectedResultException { - invocationCount++; - // avoid casts for some tests - Object o = frame.getArguments()[index]; - if (o instanceof Integer) { - return (int) o; - } - throw new UnexpectedResultException(o); - } - - } - - abstract static class Abstract { - } - - static final class BExtendsAbstract extends Abstract { - - static final BExtendsAbstract INSTANCE = new BExtendsAbstract(); - - } - - static final class CExtendsAbstract extends Abstract { - - static final CExtendsAbstract INSTANCE = new CExtendsAbstract(); - } - - interface Interface { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/UnsupportedSpecializationTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/UnsupportedSpecializationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +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.dsl.test; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; -import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported1Factory; -import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported2Factory; -import com.oracle.truffle.api.nodes.*; - -public class UnsupportedSpecializationTest { - - @Test - public void testUnsupported1() { - TestRootNode root = TestHelper.createRoot(Unsupported1Factory.getInstance()); - try { - TestHelper.executeWith(root, ""); - Assert.fail(); - } catch (UnsupportedSpecializationException e) { - Assert.assertNotNull(e.getSuppliedValues()); - Assert.assertEquals(1, e.getSuppliedValues().length); - Assert.assertEquals("", e.getSuppliedValues()[0]); - Assert.assertSame(root.getNode().getChildren().iterator().next(), e.getSuppliedNodes()[0]); - Assert.assertEquals(root.getNode(), e.getNode()); - } - } - - @NodeChild("a") - abstract static class Unsupported1 extends ValueNode { - - @Specialization - public int doInteger(@SuppressWarnings("unused") int a) { - throw new AssertionError(); - } - } - - @Test - public void testUnsupported2() { - TestRootNode root = TestHelper.createRoot(Unsupported2Factory.getInstance()); - try { - TestHelper.executeWith(root, "", 1); - Assert.fail(); - } catch (UnsupportedSpecializationException e) { - Assert.assertNotNull(e.getSuppliedValues()); - Assert.assertNotNull(e.getSuppliedNodes()); - Assert.assertEquals(3, e.getSuppliedValues().length); - Assert.assertEquals(3, e.getSuppliedNodes().length); - Assert.assertEquals("", e.getSuppliedValues()[0]); - Assert.assertEquals(false, e.getSuppliedValues()[1]); - Assert.assertEquals(null, e.getSuppliedValues()[2]); - List children = NodeUtil.findNodeChildren(root.getNode()); - Assert.assertSame(children.get(0), e.getSuppliedNodes()[0]); - Assert.assertNull(e.getSuppliedNodes()[1]); - Assert.assertSame(children.get(1), e.getSuppliedNodes()[2]); - Assert.assertEquals(root.getNode(), e.getNode()); - } - } - - @SuppressWarnings("unused") - @NodeChildren({@NodeChild("a"), @NodeChild("b")}) - abstract static class Unsupported2 extends ValueNode { - - @ShortCircuit("b") - public boolean needsB(Object a) { - return false; - } - - @Specialization - public int doInteger(int a, boolean hasB, int b) { - throw new AssertionError(); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/ExampleNode.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/ExampleNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +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.dsl.test.examples; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -@TypeSystemReference(ExampleTypes.class) -@NodeChild(value = "args", type = ExampleNode[].class) -public abstract class ExampleNode extends Node { - - public Object execute(@SuppressWarnings("unused") VirtualFrame frame) { - // will get implemented by the DSL. - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - if (this instanceof SpecializedNode) { - return ((SpecializedNode) this).getSpecializationNode().toString(); - } else { - return super.toString(); - } - } - - public static CallTarget createTarget(ExampleNode node) { - return Truffle.getRuntime().createCallTarget(new ExampleRootNode(node)); - } - - @SuppressWarnings("unchecked") - public static T getNode(CallTarget target) { - return (T) ((ExampleRootNode) ((RootCallTarget) target).getRootNode()).child; - } - - public static ExampleNode[] createArguments(int count) { - ExampleNode[] nodes = new ExampleNode[count]; - for (int i = 0; i < count; i++) { - nodes[i] = new ExampleArgumentNode(i); - } - return nodes; - } - - private static class ExampleRootNode extends RootNode { - - @Child ExampleNode child; - - public ExampleRootNode(ExampleNode child) { - this.child = child; - } - - @Override - public Object execute(VirtualFrame frame) { - return child.execute(frame); - } - - } - - private static class ExampleArgumentNode extends ExampleNode { - - private final int index; - - public ExampleArgumentNode(int index) { - this.index = index; - } - - @Override - public Object execute(VirtualFrame frame) { - Object[] arguments = frame.getArguments(); - if (index < arguments.length) { - return arguments[index]; - } - return null; - } - } - - public static CallTarget createDummyTarget(int argumentIndex) { - return Truffle.getRuntime().createCallTarget(new DummyCallRootNode(argumentIndex)); - } - - private static class DummyCallRootNode extends RootNode { - - private final int argumentIndex; - - public DummyCallRootNode(int argumentIndex) { - this.argumentIndex = argumentIndex; - } - - @Override - public Object execute(VirtualFrame frame) { - return frame.getArguments()[argumentIndex]; - } - - @Override - public String toString() { - return "DummyRootNode[arg = " + argumentIndex + "]"; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/ExampleTypes.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/ExampleTypes.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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.dsl.test.examples; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.examples.FunctionCall.Function; -import com.oracle.truffle.api.dsl.test.examples.Interop.TruffleObject; -import com.oracle.truffle.api.dsl.test.examples.RubyCall.InternalMethod; -import com.oracle.truffle.api.dsl.test.examples.RubyCall.RubyObject; -import com.oracle.truffle.api.dsl.test.examples.StableDispatch.SLFunction; - -@TypeSystem({int.class, double.class, boolean.class, TruffleObject.class, SLFunction.class, RubyObject.class, Function.class, InternalMethod.class, int[].class, double[].class, Object[].class}) -public class ExampleTypes { - - @ImplicitCast - public static double castInt(int intValue) { - return intValue; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/FunctionCall.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/FunctionCall.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +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.dsl.test.examples; - -import static com.oracle.truffle.api.dsl.test.examples.ExampleNode.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.examples.FunctionCallFactory.FunctionCallNodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This example illustrates how {@link Cached} can be used to implement function calls that use - * local state for its guards. If there are always distinct Function objects with distinct - * CallTargets then we can use the directCallFunctionGuard specialization. If there are two Function - * instances cached with the same CallTarget then we use the directCall cache. We do this because - * the directCallFunctionGuard specialization can use a faster guard. - */ -@SuppressWarnings("unused") -public class FunctionCall { - - @Test - public void testFunctionCall() { - assertEquals(2, FunctionCallNode.CACHE_SIZE); - - CallTarget dummyTarget1 = createDummyTarget(0); - CallTarget dummyTarget2 = createDummyTarget(0); - CallTarget dummyTarget3 = createDummyTarget(0); - - Function dummyFunction1 = new Function(dummyTarget1); - Function dummyFunction2 = new Function(dummyTarget2); - Function dummyFunction3 = new Function(dummyTarget2); // same target as dummyFunction2 - Function dummyFunction4 = new Function(dummyTarget3); - - FunctionCallNode node = FunctionCallNodeGen.create(createArguments(2)); - CallTarget target = createTarget(node); - assertEquals(42, target.call(dummyFunction1, 42)); - assertEquals(43, target.call(dummyFunction2, 43)); - assertEquals(44, target.call(dummyFunction3, 44)); // transition to directCall - assertEquals(2, node.directCallFunctionGuard); - assertEquals(1, node.directCall); - - assertEquals(42, target.call(dummyFunction1, 42)); - assertEquals(43, target.call(dummyFunction2, 43)); - assertEquals(2, node.directCallFunctionGuard); - assertEquals(3, node.directCall); - - assertEquals(44, target.call(dummyFunction4, 44)); // transition to indirectCall - assertEquals(2, node.directCallFunctionGuard); - assertEquals(3, node.directCall); - assertEquals(1, node.indirectCall); - - assertEquals(42, target.call(dummyFunction1, 42)); - assertEquals(43, target.call(dummyFunction2, 43)); - assertEquals(44, target.call(dummyFunction3, 44)); - assertEquals(2, node.directCallFunctionGuard); - assertEquals(3, node.directCall); - assertEquals(4, node.indirectCall); - } - - public static class FunctionCallNode extends ExampleNode { - - public static final int CACHE_SIZE = 2; - - private Function[] cachedFunctions = new Function[CACHE_SIZE]; - - private int directCallFunctionGuard; - private int directCall; - private int indirectCall; - - @Specialization(limit = "CACHE_SIZE", guards = {"function == cachedFunction", "cacheFunctionTarget(cachedFunction)"}) - public Object directCallFunctionGuard(VirtualFrame frame, Function function, Object argument, // - @Cached("function") Function cachedFunction, // - @Cached("create(cachedFunction.getTarget())") DirectCallNode callNode) { - directCallFunctionGuard++; - return callNode.call(frame, new Object[]{argument}); - } - - protected final boolean cacheFunctionTarget(Function function) { - CompilerAsserts.neverPartOfCompilation(); - if (cachedFunctions != null) { - for (int i = 0; i < cachedFunctions.length; i++) { - Function cachedFunction = cachedFunctions[i]; - if (cachedFunction == null) { - cachedFunctions[i] = function; - return true; - } else if (cachedFunction == function) { - return true; - } else if (cachedFunction.getTarget() == function.getTarget()) { - cachedFunctions = null; - return false; - } - } - } - return false; - } - - @Specialization(limit = "CACHE_SIZE", contains = "directCallFunctionGuard", guards = {"function.getTarget() == cachedTarget"}) - protected Object directCall(VirtualFrame frame, Function function, Object argument, // - @Cached("function.getTarget()") CallTarget cachedTarget, // - @Cached("create(cachedTarget)") DirectCallNode callNode) { - directCall++; - return callNode.call(frame, new Object[]{argument}); - } - - @Specialization(contains = "directCall") - protected Object indirectCall(VirtualFrame frame, Function function, Object argument, // - @Cached("create()") IndirectCallNode callNode) { - indirectCall++; - return callNode.call(frame, function.getTarget(), new Object[]{argument}); - } - } - - public static class Function { - - private final CallTarget target; - - public Function(CallTarget target) { - this.target = target; - } - - public CallTarget getTarget() { - return target; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/Interop.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/Interop.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +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.dsl.test.examples; - -import static com.oracle.truffle.api.dsl.test.examples.ExampleNode.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.examples.InteropFactory.UseInteropNodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This example aims to illustrate how the {@link Cached} annotation can be used to implement a - * cache for a simplified language interoperability pattern. - */ -public class Interop { - - @Test - public void testInterop() { - UseInterop node = UseInteropNodeGen.create(createArguments(2)); - CallTarget target = createTarget(node); - TruffleObject o1 = new TruffleObject(); - TruffleObject o2 = new TruffleObject(); - TruffleObject o3 = new TruffleObject(); - TruffleObject o4 = new TruffleObject(); - assertEquals(42, target.call(o1, 42)); - assertEquals(43, target.call(o2, 43)); - assertEquals(44, target.call(o3, 44)); - assertEquals(3, node.cached); - assertEquals(0, node.generic); - assertEquals(45, target.call(o4, 45)); // operation gets generic - assertEquals(42, target.call(o1, 42)); - assertEquals(43, target.call(o2, 43)); - assertEquals(44, target.call(o3, 44)); - assertEquals(3, node.cached); - assertEquals(4, node.generic); - } - - public static class UseInterop extends ExampleNode { - - int cached = 0; - int generic = 0; - - @Specialization(guards = "operation.accept(target)") - protected Object interopCached(VirtualFrame frame, TruffleObject target, Object value, // - @Cached("target.createOperation()") TruffleObjectOperation operation) { - cached++; - return operation.execute(frame, target, value); - } - - @Specialization(contains = "interopCached") - protected Object interopGeneric(VirtualFrame frame, TruffleObject target, Object value) { - generic++; - return target.createOperation().execute(frame, target, value); - } - } - - public abstract static class TruffleObjectOperation extends Node { - - public abstract boolean accept(TruffleObject object); - - public abstract Object execute(VirtualFrame frame, Object target, Object value); - - } - - public static class TruffleObject { - - @TruffleBoundary - public TruffleObjectOperation createOperation() { - return new TruffleObjectOperation() { - @Override - public Object execute(VirtualFrame frame, Object target, Object value) { - return value; - } - - @Override - public boolean accept(TruffleObject object) { - return TruffleObject.this == object; - } - }; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/MathPow.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/MathPow.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +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.dsl.test.examples; - -import static com.oracle.truffle.api.dsl.test.examples.ExampleNode.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.examples.MathPowFactory.MathPowNodeGen; -import com.oracle.truffle.api.nodes.*; - -/** - * This example shows possible specializations for a simplified math pow node. It demonstrates how - * multiple caches can coexist within in the same node. This example does not show the best possible - * specializations for math.pow. - * - * Note: int values are implicitly casted to double values. - */ -@SuppressWarnings("unused") -public class MathPow extends Node { - - @Test - public void testPow() { - MathPowNode node = MathPowNodeGen.create(createArguments(2)); - CallTarget target = createTarget(node); - - // start with doPowCached - assertEquals(1D, target.call(1D, 1)); - assertEquals(2D, target.call(2D, 1)); - assertEquals(3D, target.call(3D, 1)); - assertEquals(3, node.doPowCached); - assertEquals(0, node.doPowCachedExponent); - - // transition to doPowCachedExponent - assertEquals(4D, target.call(4D, 1)); - assertEquals(5D, target.call(5D, 1)); - assertEquals(6D, target.call(6D, 1)); - assertEquals(16D, target.call(4D, 2)); - assertEquals(125D, target.call(5D, 3)); - assertEquals(5, node.doPowCachedExponent); - assertEquals(0, node.doPowDoubleInt); - - // transition to doPowDoubleInt - assertEquals(4D * 4D * 4D * 4D, target.call(4D, 4)); - assertEquals(5D * 5D * 5D * 5D * 5D, target.call(5D, 5)); - assertEquals(5, node.doPowCachedExponent); - assertEquals(2, node.doPowDoubleInt); - - // transition to doPow - assertEquals(5D, target.call(5D, 1D)); - assertEquals(2D, target.call(2D, 1D)); - - assertEquals(3, node.doPowCached); - assertEquals(5, node.doPowCachedExponent); - assertEquals(2, node.doPowDoubleInt); - assertEquals(2, node.doPow); - } - - public static class MathPowNode extends ExampleNode { - - // test flags - int doPowCached; - int doPowCachedExponent; - int doPowDoubleInt; - int doPow; - - @Specialization(guards = {"base == cachedBase", "exponent == cachedExponent"}) - double doPowCached(double base, int exponent, // - @Cached("base") double cachedBase, // - @Cached("exponent") int cachedExponent, // - @Cached("cachePow(cachedBase, cachedExponent)") double cachedResult) { - doPowCached++; - return cachedResult; - } - - /* - * We could just use the doPow specialization instead. But this makes the number of doPow - * calls more difficult to assert. - */ - protected static double cachePow(double base, int exponent) { - return Math.pow(base, exponent); - } - - @Specialization(contains = "doPowCached", guards = {"exponent == cachedExponent", "cachedExponent <= 10"}) - double doPowCachedExponent(double base, int exponent, @Cached("exponent") int cachedExponent) { - doPowCachedExponent++; - double result = 1.0; - for (int i = 0; i < cachedExponent; i++) { - result *= base; - } - return result; - } - - @Specialization(contains = "doPowCachedExponent", guards = "exponent >= 0") - double doPowDoubleInt(double base, int exponent) { - doPowDoubleInt++; - // Uses binary decomposition to limit the number of - // multiplications; see the discussion in "Hacker's Delight" by Henry - // S. Warren, Jr., figure 11-6, page 213. - double b = base; - int e = exponent; - double result = 1; - while (e > 0) { - if ((e & 1) == 1) { - result *= b; - } - e >>= 1; - b *= b; - } - return result; - } - - @Specialization(contains = {"doPowCached", "doPowDoubleInt"}) - double doPow(double base, double exponent) { - doPow++; - return Math.pow(base, exponent); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/RubyCall.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/RubyCall.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +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.dsl.test.examples; - -import static com.oracle.truffle.api.dsl.test.examples.ExampleNode.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.dsl.test.examples.RubyCallFactory.RubyDispatchNodeGen; -import com.oracle.truffle.api.dsl.test.examples.RubyCallFactory.RubyHeadNodeGen; -import com.oracle.truffle.api.dsl.test.examples.RubyCallFactory.RubyLookupNodeGen; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -/** - * This example illustrates a simplified version of a Ruby function call semantics (RubyHeadNode). - * The example usage shows how methods can be redefined in this implementation. - */ -@SuppressWarnings("unused") -public class RubyCall { - - @Test - public void testCall() { - RubyHeadNode node = RubyHeadNodeGen.create(createArguments(4)); - CallTarget nodeTarget = createTarget(node); - final Object firstArgument = "someArgument"; - - // dummyMethod is just going to return the some argument of the function - final Object testMethodName = "getSomeArgument"; - // implementation returns first argument - InternalMethod aClassTestMethod = new InternalMethod(ExampleNode.createDummyTarget(3)); - // implementation returns second argument - InternalMethod bClassTestMethod = new InternalMethod(ExampleNode.createDummyTarget(4)); - // implementation returns third argument - InternalMethod cClassTestMethod = new InternalMethod(ExampleNode.createDummyTarget(5)); - - // defines hierarchy C extends B extends A - RubyClass aClass = new RubyClass("A", null); - RubyClass bClass = new RubyClass("B", aClass); - RubyClass cClass = new RubyClass("C", bClass); - - RubyObject aInstance = new RubyObject(aClass); - RubyObject bInstance = new RubyObject(bClass); - RubyObject cInstance = new RubyObject(cClass); - - // undefined method call - assertEquals(RubyObject.NIL, nodeTarget.call(cInstance, testMethodName, null, new Object[]{firstArgument})); - - // method defined in a - aClass.addMethod(testMethodName, aClassTestMethod); - assertEquals(firstArgument, nodeTarget.call(aInstance, testMethodName, null, new Object[]{firstArgument})); - assertEquals(firstArgument, nodeTarget.call(bInstance, testMethodName, null, new Object[]{firstArgument})); - assertEquals(firstArgument, nodeTarget.call(cInstance, testMethodName, null, new Object[]{firstArgument})); - - // method redefined in b - bClass.addMethod(testMethodName, bClassTestMethod); - assertEquals(firstArgument, nodeTarget.call(aInstance, testMethodName, null, new Object[]{firstArgument})); - assertEquals(firstArgument, nodeTarget.call(bInstance, testMethodName, null, new Object[]{null, firstArgument})); - assertEquals(firstArgument, nodeTarget.call(cInstance, testMethodName, null, new Object[]{null, firstArgument})); - - // method redefined in c - cClass.addMethod(testMethodName, cClassTestMethod); - assertEquals(firstArgument, nodeTarget.call(aInstance, testMethodName, null, new Object[]{firstArgument})); - assertEquals(firstArgument, nodeTarget.call(bInstance, testMethodName, null, new Object[]{null, firstArgument})); - assertEquals(firstArgument, nodeTarget.call(cInstance, testMethodName, null, new Object[]{null, null, firstArgument})); - - } - - public static class RubyHeadNode extends ExampleNode { - - @Child private RubyLookupNode lookup = RubyLookupNodeGen.create(); - @Child private RubyDispatchNode dispatch = RubyDispatchNodeGen.create(); - - @Specialization - public Object doCall(VirtualFrame frame, RubyObject receiverObject, Object methodName, Object blockObject, Object... argumentsObjects) { - InternalMethod method = lookup.executeLookup(receiverObject, methodName); - - Object[] packedArguments = new Object[argumentsObjects.length + 3]; - packedArguments[0] = method; - packedArguments[1] = receiverObject; - packedArguments[2] = blockObject; - System.arraycopy(argumentsObjects, 0, packedArguments, 3, argumentsObjects.length); - - return dispatch.executeDispatch(frame, method, packedArguments); - } - } - - public abstract static class RubyLookupNode extends Node { - - public abstract InternalMethod executeLookup(RubyObject receiver, Object method); - - @Specialization(guards = "receiver.getRubyClass() == cachedClass", assumptions = "cachedClass.getDependentAssumptions()") - protected static InternalMethod cachedLookup(RubyObject receiver, Object name, // - @Cached("receiver.getRubyClass()") RubyClass cachedClass, // - @Cached("genericLookup(receiver, name)") InternalMethod cachedLookup) { - return cachedLookup; - } - - @Specialization(contains = "cachedLookup") - protected static InternalMethod genericLookup(RubyObject receiver, Object name) { - return receiver.getRubyClass().lookup(name); - } - - } - - @ImportStatic(InternalMethod.class) - public abstract static class RubyDispatchNode extends Node { - - public abstract Object executeDispatch(VirtualFrame frame, InternalMethod function, Object[] packedArguments); - - /* - * Please note that cachedMethod != METHOD_MISSING is invoked once at specialization - * instantiation. It is never executed on the fast path. - */ - @Specialization(guards = {"method == cachedMethod", "cachedMethod != METHOD_MISSING"}) - protected static Object directCall(VirtualFrame frame, InternalMethod method, Object[] arguments, // - @Cached("method") InternalMethod cachedMethod, // - @Cached("create(cachedMethod.getTarget())") DirectCallNode callNode) { - return callNode.call(frame, arguments); - } - - /* - * The method == METHOD_MISSING can fold if the RubyLookup results just in a single entry - * returning the constant METHOD_MISSING. - */ - @Specialization(guards = "method == METHOD_MISSING") - protected static Object methodMissing(VirtualFrame frame, InternalMethod method, Object[] arguments) { - // a real implementation would do a call to a method named method_missing here - return RubyObject.NIL; - } - - @Specialization(contains = "directCall", guards = "method != METHOD_MISSING") - protected static Object indirectCall(VirtualFrame frame, InternalMethod method, Object[] arguments, // - @Cached("create()") IndirectCallNode callNode) { - return callNode.call(frame, method.getTarget(), arguments); - } - - @Override - public String toString() { - return ((SpecializedNode) this).getSpecializationNode().toString(); - } - } - - public static final class RubyObject { - - public static final RubyObject NIL = new RubyObject(null); - - private final RubyClass rubyClass; - - public RubyObject(RubyClass rubyClass) { - this.rubyClass = rubyClass; - } - - public RubyClass getRubyClass() { - return rubyClass; - } - - @Override - public String toString() { - return "RubyObject[class=" + rubyClass + "]"; - } - - } - - public static final class RubyClass /* this would extend RubyModule */{ - - private final String name; - private final RubyClass parent; // this would be a RubyModule - private final CyclicAssumption unmodified; - private final Map methods = new HashMap<>(); - private Assumption[] cachedDependentAssumptions; - private final int depth; - - public RubyClass(String name, RubyClass parent) { - this.name = name; - this.parent = parent; - this.unmodified = new CyclicAssumption("unmodified class " + name); - - // lookup depth for array allocation - RubyClass clazz = parent; - int currentDepth = 1; - while (clazz != null) { - currentDepth++; - clazz = clazz.parent; - } - this.depth = currentDepth; - } - - @TruffleBoundary - public InternalMethod lookup(Object methodName) { - InternalMethod method = methods.get(methodName); - if (method == null) { - if (parent != null) { - return parent.lookup(methodName); - } else { - return InternalMethod.METHOD_MISSING; - } - } else { - return method; - } - } - - @TruffleBoundary - public void addMethod(Object methodName, InternalMethod method) { - // check for existing method omitted for simplicity - this.methods.put(methodName, method); - this.unmodified.invalidate(); - } - - /* - * Method collects all unmodified assumptions in the class hierarchy. The result is cached - * per class to void recreation per call site. - */ - @TruffleBoundary - public Assumption[] getDependentAssumptions() { - Assumption[] dependentAssumptions = cachedDependentAssumptions; - if (dependentAssumptions != null) { - // we can use the cached dependent assumptions only if they are still valid - for (Assumption assumption : cachedDependentAssumptions) { - if (!assumption.isValid()) { - dependentAssumptions = null; - break; - } - } - } - if (dependentAssumptions == null) { - cachedDependentAssumptions = dependentAssumptions = createDependentAssumptions(); - } - return dependentAssumptions; - } - - @Override - public String toString() { - return "RubyClass[name=" + name + "]"; - } - - private Assumption[] createDependentAssumptions() { - Assumption[] dependentAssumptions; - RubyClass clazz = this; - dependentAssumptions = new Assumption[depth]; - - // populate array - int index = 0; - do { - dependentAssumptions[index] = clazz.unmodified.getAssumption(); - index++; - clazz = clazz.parent; - } while (clazz != null); - return dependentAssumptions; - } - } - - public static final class InternalMethod { - - public static final InternalMethod METHOD_MISSING = new InternalMethod(null); - - private final CallTarget target; - - public InternalMethod(CallTarget target) { - this.target = target; - } - - public CallTarget getTarget() { - return target; - } - - @Override - public String toString() { - return "InternalMethod[target=" + getTarget() + "]"; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/StableDispatch.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/examples/StableDispatch.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +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.dsl.test.examples; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -/** - * This example is based on the SLDispatchNode of SimpleLanguage. It shows how to implement a simple - * inline cache with an assumption that needs to be checked. - * - * Note that if an assumption is invalidated the specialization instantiation is removed. - */ -@SuppressWarnings("unused") -@NodeChildren({@NodeChild("function"), @NodeChild("arguments")}) -public class StableDispatch { - - public static class StableDispatchNode extends ExampleNode { - - @Specialization(guards = "function == cachedFunction", assumptions = "cachedFunction.getCallTargetStable()") - protected static Object directDispatch(VirtualFrame frame, SLFunction function, Object[] arguments, // - @Cached("function") SLFunction cachedFunction, // - @Cached("create(cachedFunction.getCallTarget())") DirectCallNode callNode) { - return callNode.call(frame, arguments); - } - - @Specialization(contains = "directDispatch") - protected static Object indirectDispatch(VirtualFrame frame, SLFunction function, Object[] arguments, // - @Cached("create()") IndirectCallNode callNode) { - return callNode.call(frame, function.getCallTarget(), arguments); - } - } - - public static final class SLFunction { - - private CallTarget callTarget; - private final CyclicAssumption callTargetStable; - - protected SLFunction(String name) { - this.callTargetStable = new CyclicAssumption(name); - } - - protected void setCallTarget(CallTarget callTarget) { - this.callTarget = callTarget; - this.callTargetStable.invalidate(); - } - - public CallTarget getCallTarget() { - return callTarget; - } - - public Assumption getCallTargetStable() { - return callTargetStable.getAssumption(); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/Compile.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/Compile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +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.dsl.test.processor; - -import static org.junit.Assert.*; - -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.tools.*; -import javax.tools.JavaFileObject.Kind; - -final class Compile implements DiagnosticListener { - private final List> errors = new ArrayList<>(); - private final Map classes; - private final String sourceLevel; - - private Compile(Class processor, String code, String sl) { - this.sourceLevel = sl; - classes = compile(processor, code); - } - - /** - * Performs compilation of given HTML page and associated Java code. - */ - public static Compile create(Class processor, String code) { - return new Compile(processor, code, "1.7"); - } - - /** Checks for given class among compiled resources. */ - public byte[] get(String res) { - return classes.get(res); - } - - /** - * Obtains errors created during compilation. - */ - public List> getErrors() { - List> err; - err = new ArrayList<>(); - for (Diagnostic diagnostic : errors) { - if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { - err.add(diagnostic); - } - } - return err; - } - - private Map compile(Class processor, final String code) { - StandardJavaFileManager sjfm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null); - - final Map class2BAOS; - class2BAOS = new HashMap<>(); - - JavaFileObject file = new SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return code; - } - }; - - JavaFileManager jfm = new ForwardingJavaFileManager(sjfm) { - @Override - public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { - if (kind == Kind.CLASS) { - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - class2BAOS.put(className.replace('.', '/') + ".class", buffer); - return new SimpleJavaFileObject(sibling.toUri(), kind) { - @Override - public OutputStream openOutputStream() { - return buffer; - } - }; - } - - if (kind == Kind.SOURCE) { - final String n = className.replace('.', '/') + ".java"; - final URI un; - try { - un = new URI("mem://" + n); - } catch (URISyntaxException ex) { - throw new IOException(ex); - } - return new VirtFO(un/* sibling.toUri() */, kind, n); - } - - throw new IllegalStateException(); - } - - @Override - public boolean isSameFile(FileObject a, FileObject b) { - if (a instanceof VirtFO && b instanceof VirtFO) { - return ((VirtFO) a).getName().equals(((VirtFO) b).getName()); - } - - return super.isSameFile(a, b); - } - - class VirtFO extends SimpleJavaFileObject { - - private final String n; - - public VirtFO(URI uri, Kind kind, String n) { - super(uri, kind); - this.n = n; - } - - private final ByteArrayOutputStream data = new ByteArrayOutputStream(); - - @Override - public OutputStream openOutputStream() { - return data; - } - - @Override - public String getName() { - return n; - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { - data.close(); - return new String(data.toByteArray()); - } - } - }; - List args = Arrays.asList("-source", sourceLevel, "-target", "1.7", // - "-processor", processor.getName()); - - ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, args, null, Arrays.asList(file)).call(); - - Map result = new HashMap<>(); - - for (Map.Entry e : class2BAOS.entrySet()) { - result.put(e.getKey(), e.getValue().toByteArray()); - } - - return result; - } - - @Override - public void report(Diagnostic diagnostic) { - errors.add(diagnostic); - } - - void assertErrors() { - assertFalse("There are supposed to be some errors", getErrors().isEmpty()); - } - - void assertNoErrors() { - assertTrue("There are supposed to be no errors: " + getErrors(), getErrors().isEmpty()); - } - - void assertError(String expMsg) { - StringBuilder sb = new StringBuilder(); - sb.append("Can't find ").append(expMsg).append(" among:"); - for (Diagnostic e : errors) { - String msg = e.getMessage(Locale.US); - if (msg.contains(expMsg)) { - return; - } - sb.append("\n"); - sb.append(msg); - } - fail(sb.toString()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +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.dsl.test.processor; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.dsl.test.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -public class LanguageRegistrationTest { - - @ExpectError("Registered language class must be public") - @TruffleLanguage.Registration(name = "myLang", version = "0", mimeType = "text/x-my") - private static final class MyLang { - } - - @ExpectError("Registered language inner-class must be static") - @TruffleLanguage.Registration(name = "myLangNonStatic", version = "0", mimeType = "text/x-my") - public final class MyLangNonStatic { - } - - @ExpectError("Registered language class must subclass TruffleLanguage") - @TruffleLanguage.Registration(name = "myLang", version = "0", mimeType = "text/x-my") - public static final class MyLangNoSubclass { - } - - @ExpectError("Language must have a public constructor accepting TruffleLanguage.Env as parameter") - @TruffleLanguage.Registration(name = "myLangNoCnstr", version = "0", mimeType = "text/x-my") - public static final class MyLangWrongConstr extends TruffleLanguage { - private MyLangWrongConstr() { - super(null); - } - - @Override - protected Object eval(Source code) throws IOException { - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal() { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return null; - } - - @Override - protected DebugSupportProvider getDebugSupport() { - return null; - } - - } - - @ExpectError("Language must have a public constructor accepting TruffleLanguage.Env as parameter") - @TruffleLanguage.Registration(name = "myLangNoCnstr", version = "0", mimeType = "text/x-my") - public static final class MyLangNoConstr extends TruffleLanguage { - public MyLangNoConstr() { - super(null); - } - - @Override - protected Object eval(Source code) throws IOException { - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal() { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return null; - } - - @Override - protected DebugSupportProvider getDebugSupport() { - return null; - } - - } - - @TruffleLanguage.Registration(name = "myLangGood", version = "0", mimeType = "text/x-my") - public static final class MyLangGood extends TruffleLanguage { - public MyLangGood(TruffleLanguage.Env env) { - super(env); - } - - @Override - protected Object eval(Source code) throws IOException { - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal() { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return null; - } - - @Override - protected DebugSupportProvider getDebugSupport() { - return null; - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/TruffleProcessorTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/TruffleProcessorTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +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.dsl.test.processor; - -import static org.junit.Assert.*; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.tools.*; - -import org.junit.*; - -import com.oracle.truffle.api.dsl.test.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.dsl.processor.verify.*; - -/** - * Verify errors emitted by the processor. - */ -public class TruffleProcessorTest { - // - // AnnotationProcessor test using the NetBeans style - // - - @Test - public void childCannotBeFinal() throws Exception { - // @formatter:off - String code = "package x.y.z;\n" + - "import com.oracle.truffle.api.nodes.Node;\n" + - "abstract class MyNode extends Node {\n" + - " @Child final MyNode first;\n" + - " MyNode(MyNode n) {\n" + - " this.first = n;\n" + - " };\n" + - "}\n"; - // @formatter:on - - Compile c = Compile.create(VerifyTruffleProcessor.class, code); - c.assertErrors(); - boolean ok = false; - StringBuilder msgs = new StringBuilder(); - for (Diagnostic e : c.getErrors()) { - String msg = e.getMessage(Locale.ENGLISH); - if (msg.contains("cannot be final")) { - ok = true; - } - msgs.append("\n").append(msg); - } - if (!ok) { - fail("Should contain warning about final:" + msgs); - } - } - - @Test - public void workAroundCannonicalDependency() throws Exception { - Class myProc = VerifyTruffleProcessor.class; - assertNotNull(myProc); - StringBuilder sb = new StringBuilder(); - sb.append("Cannot find ").append(myProc); - for (Processor load : ServiceLoader.load(Processor.class)) { - sb.append("Found ").append(load); - if (myProc.isInstance(load)) { - return; - } - } - fail(sb.toString()); - } - - // - // and now the Truffle traditional way - // - - abstract class MyNode extends Node { - @ExpectError("@Child field cannot be final") @Child final MyNode first; - - MyNode(MyNode n) { - this.first = n; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -/** - *

- * A parameter annotated with {@link Cached} in a {@link Specialization} refers to a cached - * value of a specialization instance. A cached parameter value is initialized once using the - * initializer expression at specialization instantiation. For each call of the specialization - * method the cached value is provided by using the annotated parameter from the method body. Cache - * initializers are potentially executed before guard expressions declared in - * {@link Specialization#guards()}. - *

- *

- * A typical specialization may define multiple dynamic and multiple cached parameters. Dynamic - * parameter values are typically provided by executing child nodes of the operation. Cached - * parameters are initialized and stored once per specialization instantiation. Cached parameters - * are always constant at compile time. You may verify this by invoking - * {@link CompilerAsserts#compilationConstant(Object)} on any cached parameter. For consistency - * between specialization declarations cached parameters must be declared last in a specialization - * method. - *

- *

- * The initializer expression of a cached parameter is defined using a subset of Java. This subset - * includes field/parameter accesses, function calls, type exact infix comparisons (==, !=, <, <=, - * >, >=) and integer literals. The return type of the initializer expression must be assignable to - * the parameter type. If the annotated parameter type is derived from {@link Node} then the - * {@link Node} instance is allowed to use the {@link Node#replace(Node)} method to replace itself. - * Bound elements without receivers are resolved using the following order: - *

    - *
  1. Dynamic and cached parameters of the enclosing specialization.
  2. - *
  3. Fields defined using {@link NodeField} for the enclosing node.
  4. - *
  5. Public constructors of the type of the annotated parameter using the new keyword - * as method name.
  6. - *
  7. Public and static methods or fields of the type of the annotated parameter.
  8. - *
  9. Non-private, static or virtual methods or fields of enclosing node.
  10. - *
  11. Non-private, static or virtual methods or fields of super types of the enclosing node.
  12. - *
  13. Public and static methods or fields imported using {@link ImportStatic}.
  14. - *
- * - * The following examples explain the intended use of the {@link Cached} annotation. All of the - * examples have to be enclosed in the following node declaration: - *

- * - *
- * @NodeChild("operand")
- * abstract TestNode extends Node {
- *   abstract void execute(Object operandValue);
- *   // ... example here ...
- * }
- * 
- * - *
    - *
  1. - * This example defines one dynamic and one cached parameter. The operand parameter is representing - * the dynamic value of the operand while the cachedOperand is initialized once at first execution - * of the specialization (specialization instantiation time). - * - *
    - *  @Specialization
    - *  void doCached(int operand, @Cached("operand") int cachedOperand) {
    - *      CompilerAsserts.compilationConstant(cachedOperand);
    - *      ...
    - *  }
    - *
    - *  Example executions:
    - *  execute(1) => doCached(1, 1) // new instantiation, localOperand is bound to 1
    - *  execute(0) => doCached(0, 1)
    - *  execute(2) => doCached(2, 1)
    - *
    - * 
    - * - *
  2. - *
  3. - * We extend the previous example by a guard for the cachedOperand value to be equal to the dynamic - * operand value. This specifies that the specialization is instantiated for each individual operand - * value that is provided. There are a lot of individual int values and for each - * individual int value a new specialization would get instantiated. The - * {@link Specialization#limit()} property defines a limit for the number of specializations that - * can get instantiated. If the specialization instantiation limit is reached then no further - * specializations are instantiated. Like for other specializations if there are no more - * specializations defined an {@link UnsupportedSpecializationException} is thrown. The default - * specialization instantiation limit is 3. - * - *
    - * @Specialization(guards = "operand == cachedOperand")
    - * void doCached(int operand, @Cached("operand") int cachedOperand) {
    - *    CompilerAsserts.compilationConstant(cachedOperand);
    - *    ...
    - * }
    - *
    - * Example executions:
    - * execute(0) => doCached(0, 0) // new instantiation, cachedOperand is bound to 0
    - * execute(1) => doCached(1, 1) // new instantiation, cachedOperand is bound to 1
    - * execute(1) => doCached(1, 1)
    - * execute(2) => doCached(2, 2) // new instantiation, cachedOperand is bound to 2
    - * execute(3) => throws UnsupportedSpecializationException // instantiation limit overflows
    - *
    - * 
    - * - *
  4. - *
  5. - * To handle the limit overflow we extend our example by an additional specialization named - * doNormal. This specialization has the same type restrictions but does not have local - * state nor the operand identity guard. It is also declared after doCached therefore - * it is only instantiated if the limit of the doCached specialization has been - * reached. In other words doNormal is more generic than doCached . The - * doNormal specialization uses contains="doCached" to specify - * that all instantiations of doCached get removed if doNormal is - * instantiated. Alternatively if the contains relation is omitted then all - * doCached instances remain but no new instances are created. - * - * - * @Specialization(guards = "operand == cachedOperand") - * void doCached(int operand, @Cached("operand") int cachedOperand) { - * CompilerAsserts.compilationConstant(cachedOperand); - * ... - * } - * - * @Specialization(contains = "doCached") - * void doNormal(int operand) {...} - * - * Example executions with contains = "doCached": - * execute(0) => doCached(0, 0) // new instantiation, cachedOperand is bound to 0 - * execute(1) => doCached(1, 1) // new instantiation, cachedOperand is bound to 1 - * execute(1) => doCached(1, 1) - * execute(2) => doCached(2, 2) // new instantiation, cachedOperand is bound to 2 - * execute(3) => doNormal(3) // new instantiation of doNormal due to limit overflow; doCached gets removed. - * execute(1) => doNormal(1) - * - * Example executions without contains = "doCached": - * execute(0) => doCached(0, 0) // new instantiation, cachedOperand is bound to 0 - * execute(1) => doCached(1, 1) // new instantiation, cachedOperand is bound to 1 - * execute(1) => doCached(1, 1) - * execute(2) => doCached(2, 2) // new instantiation, cachedOperand is bound to 2 - * execute(3) => doNormal(3) // new instantiation of doNormal due to limit overflow - * execute(1) => doCached(1, 1) - * - * - * - *
  6. - *
  7. - * This next example shows how methods from the enclosing node can be used to initialize cached - * parameters. Please note that the visibility of transformLocal must not be private. - * - *
    - * @Specialization
    - * void s(int operand, @Cached("transformLocal(operand)") int cachedOperand) {
    - * }
    - *
    - * int transformLocal(int operand) {
    - *     return operand & 0x42;
    - * }
    - *
    - * 
  8. - * - *
  9. - * The new keyword can be used to initialize a cached parameter using a constructor of - * the parameter type. - * - *
    - * @Specialization
    - * void s(Object operand, @Cached("new()") OtherNode someNode) {
    - *     someNode.execute(operand);
    - * }
    - *
    - * static class OtherNode extends Node {
    - *
    - *     public String execute(Object value) {
    - *         throw new UnsupportedOperationException();
    - *     }
    - * }
    - *
    - * 
    - * - *
  10. - *
  11. - * Java types without public constructor but with a static factory methods can be initialized by - * just referencing its static factory method and its parameters. In this case - * {@link BranchProfile#create()} is used to instantiate the {@link BranchProfile} instance. - * - *
    - * @Specialization
    - * void s(int operand, @Cached("create()") BranchProfile profile) {
    - * }
    - * 
    - * - *
  12. - *
- * - * @see Specialization#guards() - * @see Specialization#contains() - * @see Specialization#limit() - * @see ImportStatic - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.PARAMETER}) -public @interface Cached { - - /** - * Defines the initializer expression of the cached parameter value. - * - * @see Cached - */ - String value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/CreateCast.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/CreateCast.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Specifies a factory method that creates a {@link Node} which is used to cast this child. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface CreateCast { - - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Fallback.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Fallback.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - *

- * A method annotated with {@link Fallback} is treated as a {@link Specialization} that implicitly - * links all the guards of all other declared {@link Specialization} annotated methods of the - * operation in a negated form. As a consequence it cannot declare any other guards. The expected - * signature of the method must match to the signature of a {@link Specialization} with the - * additional limitation that only generically executable argument types are allowed. A generically - * executable argument is a an argument hat can be executed from the child {@link Node} using an - * execute method without {@link UnsupportedOperationException}. In many cases the generically - * executable type is {@link Object}. An operation is limited to just one {@link Fallback} - * specialization which is always ordered at the end of the specialization chain. - *

- * - *

- * A simple example showing the use of the {@link Fallback} annotation in a DSL operation: - *

- * - *
- * @Specialization int doInt(int a) {..}
- * @Specialization int doDouble(double a) {..}
- * @Fallback int orElse(Object a) {..}
- * 
- * - *

- * The previous example could be redeclared just using {@link Specialization} annotated methods as - * follows: - *

- * - *
- * @Specialization int doInt(int a) {..}
- * @Specialization int doDouble(double a) {..}
- * @Specialization(guard={"!isInt(a)", "!isDouble(a)"})
- * int orElse(Object a) {..}
- * 
- * - *

- * Performance note: For operations with a lot of {@link Specialization} annotated methods - * the use of {@link Fallback} might generate a guard that is very big. Try to avoid the use of - * {@link Fallback} for specializations that are significantly important for peak performance. - *

- * - * @see Specialization - * @see NodeChild - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface Fallback { - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GenerateNodeFactory.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GenerateNodeFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Annotate nodes or base classes of nodes to generate factory handlers implementing the - * {@link NodeFactory} interface. The generated factory handlers class name starts with the source - * original class and ends with 'Factory'. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface GenerateNodeFactory { - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Marks a type as being generated based on another class or method of a class. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface GeneratedBy { - - Class value(); - - String methodName() default ""; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface ImplicitCast { - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Implies.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Implies.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Experimental API. - * - * @deprecated annotation has no effect anymore. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -@Deprecated -public @interface Implies { - - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImportStatic.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImportStatic.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Imports all public and static methods and fields of the provided - * classes for the use in DSL expressions of the annotated class or its subclasses. - * - * @see Specialization#guards() - * @see Specialization#assumptions() - * @see Specialization#limit() - * @see Cached - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface ImportStatic { - - Class[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeAssumptions.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeAssumptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.*; - -/** - * @deprecated use {@link NodeField} with type {@link Assumption} instead. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -@Deprecated -public @interface NodeAssumptions { - - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChild.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChild.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * A {@link NodeChild} element defines an executable child for the enclosing {@link Node}. A - * {@link Node} contains multiple {@link NodeChildren} specified in linear execution order. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface NodeChild { - - String value() default ""; - - Class type() default Node.class; - - /** - * The {@link #executeWith()} property allows a node to pass the result of one child's - * executable as an input to another child's executable. These referenced children must be - * defined before the current node in the execution order. The current node {@link #type()} - * attribute must be set to a {@link Node} which supports the evaluated execution with the - * number of {@link #executeWith()} arguments that are defined. For example if this child is - * executed with one argument, the {@link #type()} attribute must define a node which publicly - * declares a method with the signature Object execute*(VirtualFrame, Object). - */ - String[] executeWith() default {}; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChildren.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChildren.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface NodeChildren { - - NodeChild[] value() default {}; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.util.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate - * generated node classes without using reflection. - */ -public interface NodeFactory { - - /** - * Instantiates the node using the arguments array. The arguments length and types must suffice - * one of the returned signatures in {@link #getNodeSignatures()}. If the arguments array does - * not suffice one of the node signatures an {@link IllegalArgumentException} is thrown. - * - * @param arguments the argument values - * @return the instantiated node - * @throws IllegalArgumentException - */ - T createNode(Object... arguments); - - /** - * Returns the node class that will get created by {@link #createNode(Object...)}. The node - * class does not match exactly to the instantiated object but they are guaranteed to be - * assignable. - */ - Class getNodeClass(); - - /** - * Returns a list of signatures that can be used to invoke {@link #createNode(Object...)}. - */ - List>> getNodeSignatures(); - - /** - * Returns a list of children that will be executed by the created node. This is useful for base - * nodes that can execute a variable amount of nodes. - */ - List> getExecutionSignature(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeField.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeField.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * A {@link NodeField} element defines a field for the generated {@link Node}. A {@link Node} - * contains multiple {@link NodeFields} specified in linear declaration order. The field can be - * accessed by declaring an abstract getter named - * "get" + firstLetterUpperCase({@link #name()})(). - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface NodeField { - - String name(); - - Class type(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFields.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFields.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * A {@link NodeFields} element defines a field for the generated {@link Node}. A {@link Node} - * contains multiple {@link NodeFields} specified in linear declaration order. The field can be - * accessed by declaring an abstract getter named - * "get" + firstLetterUpperCase({@link #value()})(). - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface NodeFields { - - NodeField[] value() default {}; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ShortCircuit.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ShortCircuit.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface ShortCircuit { - - String value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Specialization.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Specialization.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,354 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

- * Defines a method of a node subclass to represent one specialization of an operation. Multiple - * specializations can be defined in a node representing an operation. A specialization defines - * which kind of input is expected using the method signature and the annotation attributes. The - * specialized semantics of the operation are defined using the body of the annotated Java method. A - * specialization method must be declared in a class that is derived from {@link Node} that - * references a {@link TypeSystem}. At least one specialization must be defined per operation. If no - * specialization is valid for the given set of input values then an - * {@link UnsupportedSpecializationException} is thrown instead of invoking any specialization - * method. - *

- *

- * A specialization must have at least as many parameters as there are {@link NodeChild} annotations - * declared for the enclosing operation node. These parameters are declared in the same order as the - * {@link NodeChild} annotations (linear execution order). We call such parameters dynamic input - * parameters. Every specialization that is declared within an operation must have an equal number - * of dynamic input parameters. - *

- *

- * The supported kind of input values for a specialization are declared using guards. A - * specialization may provide declarative specifications for four kinds of guards: - *

    - *
  • Type guards optimistically assume the type of an input value. A value that matches the - * type is cast to its expected type automatically. Type guards are modeled using the parameter type - * of the specialization method. Types used for type guards must be defined in the - * {@link TypeSystem}. If the type of the parameter is {@link Object} then no type guard is used for - * the dynamic input parameter.
  • - * - *
  • Expression guards optimistically assume the return value of a user-defined expression - * to be true. Expression guards are modeled using Java expressions that return a - * boolean value. If the guard expression returns false, the - * specialization is no longer applicable and the operation is re-specialized. Guard expressions are - * declared using the {@link #guards()} attribute.
  • - * - *
  • Event guards trigger re-specialization in case an exception is thrown in the - * specialization body. The {@link #rewriteOn()} attribute can be used to declare a list of such - * exceptions. Guards of this kind are useful to avoid calculating a value twice when it is used in - * the guard and its specialization.
  • - * - *
  • Assumption guards optimistically assume that the state of an {@link Assumption} - * remains true. Assumptions can be assigned to specializations using the - * {@link #assumptions()} attribute.
  • - *
- *

- *

- * The enclosing {@link Node} of a specialization method must have at least one public - * and non-final execute method. An execute method is a method that starts with - * 'execute'. If all execute methods declare the first parameter type as {@link Frame}, - * {@link VirtualFrame} or {@link MaterializedFrame} then the same frame type can be used as - * optional first parameter of the specialization. This parameter does not count to the number of - * dynamic parameters. - *

- *

- * A specialization method may declare multiple parameters annotated with {@link Cached}. Cached - * parameters are initialized and stored once per specialization instantiation. For consistency - * between specialization declarations cached parameters must be declared last in a specialization - * method. - *

- *

- * If the operation is re-specialized or if it is executed for the first time then all declared - * specializations of the operation are tried in declaration order until the guards of the first - * specialization accepts the current input values. The new specialization is then added to the - * chain of current specialization instances which might consist of one (monomorph) or multiple - * instances (polymorph). If an assumption of an instantiated specialization is violated then - * re-specialization is triggered again. - *

- *

- * With guards in combination with cached parameters it is possible that multiple instances of the - * same specialization are created. The {@link #limit()} attribute can be used to limit the number - * of instantiations per specialization. - *

- * - * @see NodeChild - * @see ShortCircuit - * @see Fallback - * @see Cached - * @see TypeSystem - * @see TypeSystemReference - * @see UnsupportedSpecializationException - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface Specialization { - - /** - * @deprecated do not use anymore. Will get removed in the next release. - */ - @Deprecated int DEFAULT_ORDER = -1; - - /** - * @deprecated use declaration order instead. Will get removed in the next release. - */ - @Deprecated - int order() default DEFAULT_ORDER; - - /** - * References a specialization of a super class by its method name where this specialization is - * inserted before. The declaration order of a specialization is not usable for nodes where - * specializations are partly declared in the super class and partly declared in a derived - * class. By default all specializations declared in the derived class are appended to those in - * the super class. This attribute can be used to override the default behavior. - */ - String insertBefore() default ""; - - /** - *

- * Declares an event guards that trigger re-specialization in case an exception is thrown in the - * specialization body. This attribute can be used to declare a list of such exceptions. Guards - * of this kind are useful to avoid calculating a value twice when it is used in the guard and - * its specialization. - *

- * - *

- * If an event guard exception is triggered then all instantiations of this specialization are - * removed. If one of theses exceptions is thrown once then no further instantiations of this - * specialization are going to be created for this node. A specialization that rewrites on an - * exception must ensure that no non-repeatable side-effect is caused until the rewrite is - * triggered. - *

- * - * Example usage: - * - *
-     * @Specialization(rewriteOn = ArithmeticException.class)
-     * int doAddNoOverflow(int a, int b) {
-     *     return ExactMath.addExact(a, b);
-     * }
-     * @Specialization
-     * long doAddWithOverflow(int a, int b) {
-     *     return a + b;
-     * }
-     * ...
-     * Example executions:
-     *   execute(Integer.MAX_VALUE - 1, 1) => doAddNoOverflow(Integer.MAX_VALUE - 1, 1)
-     *   execute(Integer.MAX_VALUE, 1)     => doAddNoOverflow(Integer.MAX_VALUE, 1)
-     *                                     => throws ArithmeticException
-     *                                     => doAddWithOverflow(Integer.MAX_VALUE, 1)
-     *   execute(Integer.MAX_VALUE - 1, 1) => doAddWithOverflow(Integer.MAX_VALUE - 1, 1)
-     * 
- * - *

- * - * @see ExactMath#addExact(int, int) - */ - Class[] rewriteOn() default {}; - - /** - *

- * Declares other specializations of the same node to be contained by this specialization. Other - * specializations are references using their unique method name. If this specialization is - * instantiated then all contained specialization instances are removed and never instantiated - * again for this node instance. Therefore this specialization should handle strictly more - * inputs than which were handled by the contained specialization, otherwise the removal of the - * contained specialization will lead to unspecialized types of input values. The contains - * declaration is transitive for multiple involved specializations. - *

- * Example usage: - * - *
-     * @Specialization(guards = "b == 2")
-     * void doDivPowerTwo(int a, int b) {
-     *     return a >> 1;
-     * }
-     * @Specialization(contains ="doDivPowerTwo", guards = "b > 0")
-     * void doDivPositive(int a, int b) {
-     *     return a / b;
-     * }
-     * ...
-     * Example executions with contains="doDivPowerTwo":
-     *   execute(4, 2) => doDivPowerTwo(4, 2)
-     *   execute(9, 3) => doDivPositive(9, 3) // doDivPowerTwo instances get removed
-     *   execute(4, 2) => doDivPositive(4, 2)
-     * Same executions without contains="doDivPowerTwo"
-     *   execute(4, 2) => doDivPowerTwo(4, 2)
-     *   execute(9, 3) => doDivPositive(9, 3)
-     *   execute(4, 2) => doDivPowerTwo(4, 2)
-     * 
- * - *

- * - * @see #guards() - */ - String[] contains() default {}; - - /** - *

- * Declares boolean expressions that define whether or not input values are - * applicable to this specialization instance. Guard expressions must always return the same - * result for each combination of the enclosing node instance and the bound input values. - *

- *

- * If a guard expression does not bind any dynamic input parameters then the DSL assumes that - * the result will not change for this node after specialization instantiation. The DSL asserts - * this assumption if assertions are enabled (-ea). - *

- *

- * Guard expressions are defined using a subset of Java. This subset includes field/parameter - * accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, >=), logical - * negation (!), logical disjunction (||) and integer literals. The return type of guard - * expressions must be boolean. Bound elements without receivers are resolved using - * the following order: - *

    - *
  1. Dynamic and cached parameters of the enclosing specialization.
  2. - *
  3. Fields defined using {@link NodeField} for the enclosing node.
  4. - *
  5. Non-private, static or virtual methods or fields of enclosing node.
  6. - *
  7. Non-private, static or virtual methods or fields of super types of the enclosing node.
  8. - *
  9. Public and static methods or fields imported using {@link ImportStatic}.
  10. - *
- *

- *

- * Example usage: - * - *

-     * static boolean acceptOperand(int operand) {
-     *     assert operand <= 42;
-     *     return operand & 1 == 1;
-     * }
-     * @Specialization(guards = {"operand <= 42", "acceptOperand(operand)"})
-     * void doSpecialization(int operand) {...}
-     * 
- * - *

- * - * @see Cached - * @see ImportStatic - */ - String[] guards() default {}; - - /** - *

- * Declares assumption guards that optimistically assume that the state of an {@link Assumption} - * remains valid. Assumption expressions are cached once per specialization instantiation. If - * one of the returned assumptions gets invalidated then the specialization instance is removed. - * If the assumption expression returns an array of assumptions then all assumptions of the - * array are checked. This is limited to one-dimensional arrays. - *

- *

- * Assumption expressions are defined using a subset of Java. This subset includes - * field/parameter accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, - * >=), logical negation (!), logical disjunction (||) and integer literals. The return type of - * the expression must be {@link Assumption} or an array of {@link Assumption} instances. - * Assumption expressions are not allowed to bind to dynamic parameter values of the - * specialization. Bound elements without receivers are resolved using the following order: - *

    - *
  1. Cached parameters of the enclosing specialization.
  2. - *
  3. Fields defined using {@link NodeField} for the enclosing node.
  4. - *
  5. Non-private, static or virtual methods or fields of enclosing node.
  6. - *
  7. Non-private, static or virtual methods or fields of super types of the enclosing node.
  8. - *
  9. Public and static methods or fields imported using {@link ImportStatic}.
  10. - *
- *

- * - *

- * Example usage: - * - *

-     * static abstract class DynamicObject() {
-     *      abstract Shape getShape();
-     *      ...
-     * }
-     * static abstract class Shape() {
-     *      abstract Assumption getUnmodifiedAssuption();
-     *      ...
-     * }
-     * @Specialization(guards = "operand.getShape() == cachedShape", assumptions = "cachedShape.getUnmodifiedAssumption()")
-     * void doAssumeUnmodifiedShape(DynamicObject operand, @Cached("operand.getShape()") Shape cachedShape) {...}
-     * 
- * - *

- * - * @see Cached - * @see ImportStatic - */ - String[] assumptions() default {}; - - /** - *

- * Declares the expression that limits the number of specialization instantiations. The default - * limit for specialization instantiations is defined as "3". If the limit is - * exceeded no more instantiations of the enclosing specialization method are created. Please - * note that the existing specialization instantiations are not removed from the - * specialization chain. You can use {@link #contains()} to remove unnecessary specializations - * instances. - *

- *

- * The limit expression is defined using a subset of Java. This subset includes field/parameter - * accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, >=), logical - * negation (!), logical disjunction (||) and integer literals. The return type of the limit - * expression must be int. Limit expressions are not allowed to bind to dynamic - * parameter values of the specialization. Bound elements without receivers are resolved using - * the following order: - *

    - *
  1. Cached parameters of the enclosing specialization.
  2. - *
  3. Fields defined using {@link NodeField} for the enclosing node.
  4. - *
  5. Non-private, static or virtual methods or fields of enclosing node.
  6. - *
  7. Non-private, static or virtual methods or fields of super types of the enclosing node.
  8. - *
  9. Public and static methods or fields imported using {@link ImportStatic}.
  10. - *
- *

- * - *

- * Example usage: - * - *

-     * static int getCacheLimit() {
-     *     return Integer.parseInt(System.getProperty("language.cacheLimit"));
-     * }
-     * @Specialization(guards = "operand == cachedOperand", limit = "getCacheLimit()")
-     * void doCached(Object operand, @Cached("operand") Object cachedOperand) {...}
-     * 
- * - *

- * - * @see #guards() - * @see #contains() - * @see Cached - * @see ImportStatic - */ - String limit() default ""; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCast.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCast.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Overrides the standard way of casting a certain type in a {@link TypeSystem}. This is useful for - * types where the guest language specific type cast can be implemented more efficiently than an - * instanceof check. The annotated method must be contained in a {@link TypeSystem} annotated class. - * Type checks must conform to the following signature: public static Type as{TypeName}(Object - * value). The casted type must be a type declared in the {@link TypeSystem}. - * - *

- * If no {@link TypeCast} is declared then the type system implicitly uses a type cast that can be - * declared as follows: - * - *

- * {@literal @}TypeCast(Type.class)
- * public static Type asType(Object value) {
- *         return (Type) value;
- * }
- * 
- * - * @see TypeCheck - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface TypeCast { - - Class value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCheck.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCheck.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -/** - * Overrides the standard way of checking for a certain type in a {@link TypeSystem}. This is useful - * for types where the guest language specific type check can be implemented more efficiently than a - * direct cast. The annotated method must be contained in a {@link TypeSystem} annotated class. Type - * checks must conform to the following signature: public static boolean is{TypeName}(Object - * value). The checked type must be a type declared in the {@link TypeSystem}. - * - *

- * If no {@link TypeCheck} is declared then the type system implicitly uses a type check that can be - * declared as follows: - * - *

- * {@literal @}TypeCheck(Type.class)
- * public static boolean isType(Object value) {
- *         return value instanceof Type;
- * }
- * 
- * - * @see TypeCast - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD}) -public @interface TypeCheck { - - Class value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - *

- * Each {@link Node} has one {@link TypeSystem} at its root to define the types that can be used - * throughout the system. Multiple {@link TypeSystem}s are allowed, but they cannot be mixed inside - * a single {@link Node} hierarchy. A {@link TypeSystem} defines a list of types as its child - * elements, in which every type precedes its super types.The latter condition ensures that the most - * concrete type is found first when searching the list sequentially for the type of a given generic - * value. - *

- * - *

- * Each {@link #value()} is represented as a java type. A type can specify two annotations: - * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic - * value matches to the current type. The {@link TypeCast} casts a generic type value to the current - * type. If the {@link TypeCheck} and {@link TypeCast} annotations are not declared in the - * {@link TypeSystem} the a default implementation is provided. The default implementation of - * {@link TypeCheck} returns true only on an exact type match and {@link TypeCast} is - * only a cast to this type. Specified methods with {@link TypeCheck} and {@link TypeCast} may be - * used to extend the definition of a type in the language. In our example, the - * isInteger and asInteger methods are defined in a way so that they - * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example - * points out how we express implicit type conversions. - *

- * - *

- * Example: The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and - * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent - * all values. - * - *

- *
- * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
- * public abstract class ExampleTypeSystem {
- *
- *     {@literal @}TypeCheck
- *     public boolean isInteger(Object value) {
- *         return value instanceof Integer || value instanceof Double;
- *     }
- *
- *     {@literal @}TypeCast
- *     public double asInteger(Object value) {
- *         return ((Number)value).doubleValue();
- *     }
- * }
- * 
- * - * - * @see TypeCast - * @see TypeCheck - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface TypeSystem { - - /** - * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type. - */ - Class[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one - * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy. - * - * @see TypeSystem - * @see Node - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface TypeSystemReference { - - /** The {@link TypeSystem} java type. */ - Class value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl; - -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.nodes.*; - -/** - * Thrown by the generated code of Truffle-DSL if no compatible Specialization could be found for - * the provided values. - */ -public final class UnsupportedSpecializationException extends RuntimeException { - - private static final long serialVersionUID = -2122892028296836269L; - - private final Node node; - private final Node[] suppliedNodes; - private final Object[] suppliedValues; - - @TruffleBoundary - public UnsupportedSpecializationException(Node node, Node[] suppliedNodes, Object... suppliedValues) { - Objects.requireNonNull(suppliedNodes, "The suppliedNodes parameter must not be null."); - if (suppliedNodes.length != suppliedValues.length) { - throw new IllegalArgumentException("The length of suppliedNodes must match the length of suppliedValues."); - } - this.node = node; - this.suppliedNodes = suppliedNodes; - this.suppliedValues = suppliedValues; - } - - @Override - public String getMessage() { - return String.format("Unexpected values provided for %s: %s", node, Arrays.toString(suppliedValues)); - } - - /** - * Returns the {@link Node} that caused the this {@link UnsupportedSpecializationException}. - */ - public Node getNode() { - return node; - } - - /** - * Returns the children of the {@link Node} returned by {@link #getNode()} which produced the - * values returned by {@link #getSuppliedValues()}. The array returned by - * {@link #getSuppliedNodes()} has the same length as the array returned by - * {@link #getSuppliedValues()}. Never returns null. - */ - public Node[] getSuppliedNodes() { - return suppliedNodes; - } - - /** - * Returns the dynamic values that were supplied to the node.The array returned by - * {@link #getSuppliedNodes()} has the same length as the array returned by - * {@link #getSuppliedValues()}. Never returns null. - */ - public Object[] getSuppliedValues() { - return suppliedValues; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLMetadata.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLMetadata.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -/** - * This is NOT public API. Do not use directly. This code may change without notice. - */ -public final class DSLMetadata { - - public static final Class[] EMPTY_CLASS_ARRAY = new Class[]{}; - public static final DSLMetadata NONE = new DSLMetadata(null, EMPTY_CLASS_ARRAY, EMPTY_CLASS_ARRAY, EMPTY_CLASS_ARRAY, 0, 0); - - private final Class specializationClass; - private final Class[] includes; - private final Class[] excludedBy; - private final Class[] specializedTypes; - - private final int costs; - private final int order; - - public DSLMetadata(Class specializationClass, Class[] includes, Class[] excludes, Class[] specializedTypes, int costs, int order) { - this.specializationClass = specializationClass; - this.includes = includes; - this.excludedBy = excludes; - this.specializedTypes = specializedTypes; - this.costs = costs; - this.order = order; - } - - public Class getSpecializationClass() { - return specializationClass; - } - - public Class[] getSpecializedTypes() { - return specializedTypes; - } - - Class[] getIncludes() { - return includes; - } - - Class[] getExcludedBy() { - return excludedBy; - } - - int getCosts() { - return costs; - } - - int getOrder() { - return order; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLNode.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import com.oracle.truffle.api.nodes.*; - -/** - * This is NOT public API. Do not use directly. This code may change without notice. - */ -public interface DSLNode { - - DSLMetadata getMetadata0(); - - void adoptChildren0(Node other, Node next); - - void updateTypes0(Class[] types); - - Node getNext0(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLOptions.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLOptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import java.lang.annotation.*; - -/** - * Internal DSL options to tune the generated code. These are expert options and not intended to be - * changed used for guest language implementations. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface DSLOptions { - - /** Flag has no effect anymore. Is going to be removed soon. */ - @Deprecated - boolean useNewLayout() default true; - - /** - * Lazy class loading ensures that all generated specialization classes are loaded lazily. - * Disabling this feature will eagerly load all classes but will also reduce the generated code - * size. - */ - boolean useLazyClassLoading() default true; - - /** - * Sets the optimization strategy for implicit casts. - */ - ImplicitCastOptimization implicitCastOptimization() default ImplicitCastOptimization.DUPLICATE_TAIL; - - /** Not yet implemented. */ - boolean useDisjunctiveMethodGuardOptimization() default true; - - public enum ImplicitCastOptimization { - - /** Perform no informed optimization for implicit casts. */ - NONE, - - /** Duplicate specializations for each used implicit cast combination. */ - DUPLICATE_TAIL, - - /** - * Use the same specialization for multiple combinations of implicit casts and specialize - * them independently. Not yet fully implemented. - */ - MERGE_CASTS; - - public boolean isNone() { - return this == NONE; - } - - public boolean isDuplicateTail() { - return this == DUPLICATE_TAIL; - } - - public boolean isMergeCasts() { - return this == MERGE_CASTS; - } - } - - public enum TypeBoxingOptimization { - /** Perform the optimization for all types. */ - ALWAYS, - /** Perform the optimization just for primitive types. */ - PRIMITIVE, - /** Perform the optimization for no types. */ - NONE; - } - - /** - * Defines the range of the generation of type specialized execute methods for return types and - * for specialized parameter types. A type specialized execute method is generated as soon as - * one declared type is either returned or used a specialized parameter. - */ - TypeBoxingOptimization monomorphicTypeBoxingOptimization() default TypeBoxingOptimization.PRIMITIVE; - - /** - * Defines the range of types for which type specialized execute methods should be used for - * polymorphic operations. - */ - TypeBoxingOptimization polymorphicTypeBoxingElimination() default TypeBoxingOptimization.PRIMITIVE; - - /** - * Defines the range of types for which type specialized execute methods for implicit cast - * optimizations are used. This option only has an effect if - * {@link ImplicitCastOptimization#DUPLICATE_TAIL} or - * {@link ImplicitCastOptimization#MERGE_CASTS} is set in {@link #implicitCastOptimization()}. - */ - TypeBoxingOptimization implicitTypeBoxingOptimization() default TypeBoxingOptimization.PRIMITIVE; - - /** - * Defines range of specialization return types in which the void boxing optimization is used. - * Void boxing generates an extra execute method with {@link Void} return type in order to avoid - * boxing and type checking of the return type in case the return type is not needed. For this - * to work the operation class needs to provide an overridable execute method returning - * {@link Void}. - */ - TypeBoxingOptimization voidBoxingOptimization() default TypeBoxingOptimization.PRIMITIVE; - - public enum FallbackOptimization { - /** Always generate an optimized fallback specialization. */ - ALWAYS, - - /** - * Only generate an optimized fallback specialization if a method annotated with @Fallback - * is used in the operation. - */ - DECLARED, - - /** - * Never generate an optimized fallback specialization. Please be aware that triggering a @Fallback - * case without optimization will also invalidate your compiled code. - */ - NEVER; - } - - /** Defines the optimization strategy that is used to optimize @Fallback annotated methods. */ - FallbackOptimization optimizeFallback() default FallbackOptimization.DECLARED; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.api.nodes.*; - -/** Contains utility classes shared across generated DSLNode implementations. */ -public class DSLShare { - - public static boolean isExcluded(Node currentNode, DSLMetadata otherMetadata) { - assert otherMetadata.getExcludedBy().length > 0 : "At least one exclude must be defined for isIncluded."; - Node cur = findRoot(currentNode); - while (cur != null) { - Class curClass = cur.getClass(); - if (curClass == otherMetadata.getSpecializationClass()) { - return true; - } else if (containsClass(otherMetadata.getExcludedBy(), cur)) { - return true; - } - cur = getNext(cur); - } - return false; - } - - private static boolean includes(Node oldNode, DSLNode newNode) { - return containsClass(newNode.getMetadata0().getIncludes(), oldNode); - } - - public static T rewrite(final Node thisNode, final T newNode, final String message) { - return thisNode.atomic(new Callable() { - public T call() { - assert newNode != null; - if (getNext(thisNode) != null || getPrevious(thisNode) != null) { - // already polymorphic -> append - return appendPolymorphic(findUninitialized(thisNode), newNode); - } else if (includes(thisNode, newNode)) { - // included -> remains monomorphic - newNode.adoptChildren0(thisNode, null); - return thisNode.replace(newNode, message); - } else { - // goto polymorphic - return null; - } - } - }); - } - - @SuppressWarnings("unchecked") - public static T findRoot(T node) { - Node prev = node; - Node cur; - do { - cur = prev; - prev = getPrevious(cur); - } while (prev != null); - return (T) cur; - } - - private static Node findUninitialized(Node node) { - Node next = node; - Node cur; - do { - cur = next; - next = getNext(cur); - } while (next != null); - return cur; - } - - public static T rewriteUninitialized(final Node uninitialized, final T newNode) { - return uninitialized.atomic(new Callable() { - public T call() { - Node prev = getPrevious(uninitialized); - if (prev == null) { - newNode.adoptChildren0(uninitialized, null); - return uninitialized.replace(newNode, "Uninitialized monomorphic"); - } else { - return appendPolymorphic(uninitialized, newNode); - } - } - }); - - } - - public static T rewriteToPolymorphic(final Node oldNode, final DSLNode uninitializedDSL, final T polymorphic, final DSLNode currentCopy, final DSLNode newNodeDSL, - final String message) { - return oldNode.atomic(new Callable() { - public T call() { - assert getNext(oldNode) == null; - assert getPrevious(oldNode) == null; - assert newNodeDSL != null; - - Node uninitialized = (Node) uninitializedDSL; - Node newNode = (Node) newNodeDSL; - polymorphic.adoptChildren0(oldNode, (Node) currentCopy); - - updateSourceSection(oldNode, uninitialized); - // new specialization - updateSourceSection(oldNode, newNode); - newNodeDSL.adoptChildren0(null, uninitialized); - currentCopy.adoptChildren0(null, newNode); - - oldNode.replace(polymorphic, message); - - assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized; - assert uninitializedDSL.getNext0() == null; - return polymorphic; - } - }); - } - - private static void updateSourceSection(Node oldNode, Node newNode) { - if (newNode.getSourceSection() == null) { - newNode.assignSourceSection(oldNode.getSourceSection()); - } - } - - private static Class[] mergeTypes(DSLNode node, Class[] types) { - Class[] specializedTypes = node.getMetadata0().getSpecializedTypes(); - if (specializedTypes.length == 0) { - return null; - } else if (types == null) { - return Arrays.copyOf(specializedTypes, specializedTypes.length); - } else { - for (int i = 0; i < specializedTypes.length; i++) { - if (specializedTypes[i] != types[i]) { - types[i] = Object.class; - } - } - return types; - } - } - - private static T appendPolymorphic(Node uninitialized, T newNode) { - Class[] includes = newNode.getMetadata0().getIncludes(); - Node cur = getPrevious(uninitialized); - Node prev = uninitialized; - int depth = 0; - Class[] types = null; - while (cur != null) { - if (containsClass(includes, cur)) { - cur.replace(prev, "Included in other specialization"); - cur = prev; - } else { - depth++; - types = mergeTypes((DSLNode) cur, types); - } - prev = cur; - cur = getPrevious(cur); - } - assert prev.getCost() == NodeCost.POLYMORPHIC; - - updateSourceSection(prev, newNode); - if (depth <= 1) { - newNode.adoptChildren0(prev, null); - return prev.replace(newNode, "Polymorphic to monomorphic."); - } else { - newNode.adoptChildren0(null, uninitialized); - ((DSLNode) prev).updateTypes0(mergeTypes(newNode, types)); - return uninitialized.replace(newNode, "Appended polymorphic"); - } - } - - private static boolean containsClass(Class[] classList, Node node) { - Class nodeClass = node.getClass(); - for (Class toCheck : classList) { - if (nodeClass == toCheck) { - if (node.getCost() == NodeCost.UNINITIALIZED) { - /* - * In case a specialization is excluded by the fallback specialization the - * uninitialized class is used as exclusion class. Because the fallback field in - * the uninitialized specialization is not accessible we use the costs to check - * if the fallback was reached or not. In case the fallback was reached in the - * uninitialized version the cost is MONOMORPHIC, otherwise it is UNINITIALIZED. - */ - continue; - } - return true; - } - } - return false; - } - - private static Node getNext(Node node) { - return ((DSLNode) node).getNext0(); - } - - private static Node getPrevious(Node node) { - Node parent = node.getParent(); - if (parent instanceof DSLNode && getNext(parent) == node) { - return parent; - } else { - return null; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/NodeFactoryBase.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/NodeFactoryBase.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import java.util.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This is NOT public API. Do not use directly. This code may change without notice. - */ -public abstract class NodeFactoryBase implements NodeFactory { - - private final Class nodeClass; - private final Class[][] nodeSignatures; - private final Class[] executionSignatures; - - @SuppressWarnings("unchecked") - public NodeFactoryBase(Class nodeClass, Class[] executionSignatures, Class[][] nodeSignatures) { - this.nodeClass = nodeClass; - this.nodeSignatures = nodeSignatures; - this.executionSignatures = (Class[]) executionSignatures; - } - - public abstract T createNode(Object... arguments); - - public final Class getNodeClass() { - return nodeClass; - } - - public final List>> getNodeSignatures() { - List>> signatures = new ArrayList<>(); - for (int i = 0; i < nodeSignatures.length; i++) { - signatures.add(Arrays.asList(nodeSignatures[i])); - } - return signatures; - } - - public final List> getExecutionSignature() { - return Arrays.asList(executionSignatures); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SlowPathEvent.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SlowPathEvent.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,227 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Lazy rewrite event that implements {@link CharSequence} to be provided as message in - * {@link Node#replace(Node, CharSequence)}. - */ -abstract class SlowPathEvent implements CharSequence { - - protected final SpecializationNode source; - protected final String reason; - protected final Frame frame; - private String message; - - SlowPathEvent(SpecializationNode source, String reason, Frame frame) { - this.source = source; - this.reason = reason; - this.frame = frame; - } - - public int length() { - return getMessage().length(); - } - - public char charAt(int index) { - return getMessage().charAt(index); - } - - public CharSequence subSequence(int start, int end) { - return getMessage().subSequence(start, end); - } - - @Override - public String toString() { - return getMessage(); - } - - private String getMessage() { - if (message == null) { - message = createMessage(); - } - return message; - } - - private String createMessage() { - StringBuilder builder = new StringBuilder(); - builder.append(source); - builder.append(" "); - builder.append(reason); - Object[] values = getValues(); - if (values.length > 0) { - builder.append(" with parameters ("); - String sep = ""; - for (Object value : values) { - builder.append(sep); - if (value == null) { - builder.append("null"); - } else { - builder.append(value).append(" (").append(value.getClass().getSimpleName()).append(")"); - } - - sep = ", "; - } - builder.append(")"); - } - return builder.toString(); - } - - public abstract Object[] getValues(); - - static class SlowPathEvent0 extends SlowPathEvent { - - private static final Object[] EMPTY = new Object[0]; - - public SlowPathEvent0(SpecializationNode source, String reason, Frame frame) { - super(source, reason, frame); - } - - @Override - public final Object[] getValues() { - return EMPTY; - } - - } - - static class SlowPathEvent1 extends SlowPathEvent { - - protected final Object o1; - - public SlowPathEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { - super(source, reason, frame); - this.o1 = o1; - } - - @Override - public final Object[] getValues() { - return new Object[]{o1}; - } - - } - - static class SlowPathEvent2 extends SlowPathEvent { - - protected final Object o1; - protected final Object o2; - - public SlowPathEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { - super(source, reason, frame); - this.o1 = o1; - this.o2 = o2; - } - - @Override - public final Object[] getValues() { - return new Object[]{o1, o2}; - } - - } - - static class SlowPathEvent3 extends SlowPathEvent { - - protected final Object o1; - protected final Object o2; - protected final Object o3; - - public SlowPathEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { - super(source, reason, frame); - this.o1 = o1; - this.o2 = o2; - this.o3 = o3; - } - - @Override - public final Object[] getValues() { - return new Object[]{o1, o2, o3}; - } - - } - - static class SlowPathEvent4 extends SlowPathEvent { - - protected final Object o1; - protected final Object o2; - protected final Object o3; - protected final Object o4; - - public SlowPathEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - super(source, reason, frame); - this.o1 = o1; - this.o2 = o2; - this.o3 = o3; - this.o4 = o4; - } - - @Override - public final Object[] getValues() { - return new Object[]{o1, o2, o3, o4}; - } - - } - - static class SlowPathEvent5 extends SlowPathEvent { - - protected final Object o1; - protected final Object o2; - protected final Object o3; - protected final Object o4; - protected final Object o5; - - public SlowPathEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - super(source, reason, frame); - this.o1 = o1; - this.o2 = o2; - this.o3 = o3; - this.o4 = o4; - this.o5 = o5; - } - - @Override - public final Object[] getValues() { - return new Object[]{o1, o2, o3, o4, o5}; - } - - } - - static class SlowPathEventN extends SlowPathEvent { - - protected final Object[] args; - - public SlowPathEventN(SpecializationNode source, String reason, Frame frame, Object... args) { - super(source, reason, frame); - this.args = args; - } - - @Override - public final Object[] getValues() { - return args; - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,866 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent0; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent1; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent2; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent3; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent4; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent5; -import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEventN; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Internal implementation dependent base class for generated specialized nodes. - */ -@NodeInfo(cost = NodeCost.NONE) -@SuppressWarnings("unused") -public abstract class SpecializationNode extends Node { - - @Child protected SpecializationNode next; - - final int index; - - public SpecializationNode() { - this(-1); - } - - public SpecializationNode(int index) { - this.index = index; - } - - @Override - public final NodeCost getCost() { - return NodeCost.NONE; - } - - public void reset() { - SpecializationNode start = findStart(); - SpecializationNode end = findEnd(); - if (start != end) { - start.replace(end, "reset specialization"); - } - } - - public static Node updateRoot(Node node) { - updateRootImpl(((SpecializedNode) node).getSpecializationNode(), node); - return node; - } - - private static void updateRootImpl(SpecializationNode start, Node node) { - NodeFieldAccessor[] fields = NodeClass.get(start).getFields(); - for (int i = fields.length - 1; i >= 0; i--) { - NodeFieldAccessor f = fields[i]; - if (f.getName().equals("root")) { - f.putObject(start, node); - break; - } - } - if (start.next != null) { - updateRootImpl(start.next, node); - } - } - - protected final SpecializationNode polymorphicMerge(SpecializationNode newNode, SpecializationNode merged) { - if (merged == newNode && count() <= 2) { - return removeSame(new SlowPathEvent0(this, "merged polymorphic to monomorphic", null)); - } - return merged; - } - - public final NodeCost getNodeCost() { - switch (count()) { - case 0: - case 1: - return NodeCost.UNINITIALIZED; - case 2: - return NodeCost.MONOMORPHIC; - default: - return NodeCost.POLYMORPHIC; - } - } - - protected abstract Node[] getSuppliedChildren(); - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame) { - if (isIdentical(newNode, frame)) { - return this; - } - return next != null ? next.merge(newNode, frame) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1) { - if (isIdentical(newNode, frame, o1)) { - return this; - } - return next != null ? next.merge(newNode, frame, o1) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2) { - if (isIdentical(newNode, frame, o1, o2)) { - return this; - } - return next != null ? next.merge(newNode, frame, o1, o2) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { - if (isIdentical(newNode, frame, o1, o2, o3)) { - return this; - } - return next != null ? next.merge(newNode, frame, o1, o2, o3) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { - if (isIdentical(newNode, frame, o1, o2, o3, o4)) { - return this; - } - return next != null ? next.merge(newNode, frame, o1, o2, o3, o4) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - if (isIdentical(newNode, frame, o1, o2, o3, o4, o5)) { - return this; - } - return next != null ? next.merge(newNode, frame, o1, o2, o3, o4, o5) : newNode; - } - - protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object... args) { - if (isIdentical(newNode, frame, args)) { - return this; - } - return next != null ? next.merge(newNode, frame, args) : newNode; - } - - protected boolean isSame(SpecializationNode other) { - return getClass() == other.getClass(); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - return isSame(newNode); - } - - protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object... args) { - return isSame(newNode); - } - - protected final int countSame(SpecializationNode node) { - return findStart().countSameImpl(node); - } - - private int countSameImpl(SpecializationNode node) { - if (next != null) { - return next.countSameImpl(node) + (isSame(node) ? 1 : 0); - } else { - return 0; - } - } - - @Override - public final boolean equals(Object obj) { - if (obj instanceof SpecializationNode) { - return ((SpecializationNode) obj).isSame(this); - } - return super.equals(obj); - } - - @Override - public final int hashCode() { - return index; - } - - private int count() { - return next != null ? next.count() + 1 : 1; - } - - private SpecializationNode findEnd() { - SpecializationNode node = this; - while (node.next != null) { - node = node.next; - } - return node; - } - - protected final Object removeThis(final CharSequence reason, Frame frame) { - return removeThisImpl(reason).acceptAndExecute(frame); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object o1) { - return removeThisImpl(reason).acceptAndExecute(frame, o1); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2) { - return removeThisImpl(reason).acceptAndExecute(frame, o1, o2); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3) { - return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3, o4); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3, o4, o5); - } - - protected final Object removeThis(final CharSequence reason, Frame frame, Object... args) { - return removeThisImpl(reason).acceptAndExecute(frame, args); - } - - private SpecializationNode removeThisImpl(final CharSequence reason) { - this.replace(this.next, reason); - return findEnd().findStart(); - } - - protected final SpecializationNode removeSame(final CharSequence reason) { - SpecializationNode start = SpecializationNode.this.findStart(); - SpecializationNode current = start; - while (current != null) { - if (current.isSame(SpecializationNode.this)) { - NodeUtil.nonAtomicReplace(current, current.next, reason); - if (current == start) { - start = start.next; - } - } - current = current.next; - } - return SpecializationNode.this.findEnd().findStart(); - } - - /** Find the topmost of the specialization chain. */ - private SpecializationNode findStart() { - SpecializationNode node = this; - Node parent = this.getParent(); - while (parent instanceof SpecializationNode) { - SpecializationNode parentCast = ((SpecializationNode) parent); - if (parentCast.next != node) { - break; - } - node = parentCast; - parent = node.getParent(); - } - return node; - } - - private Node findRoot() { - return findStart().getParent(); - } - - private SpecializedNode findSpecializedNode() { - return (SpecializedNode) findEnd().findStart().getParent(); - } - - private static SpecializationNode removeSameImpl(SpecializationNode toRemove, CharSequence reason) { - SpecializationNode start = toRemove.findStart(); - SpecializationNode current = start; - while (current != null) { - if (current.isSame(toRemove)) { - NodeUtil.nonAtomicReplace(current, current.next, reason); - if (current == start) { - start = start.next; - } - } - current = current.next; - } - return toRemove.findEnd().findStart(); - } - - public Object acceptAndExecute(Frame frame) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object o1) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object o1, Object o2) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3, Object o4) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - throw new UnsupportedOperationException(); - } - - public Object acceptAndExecute(Frame frame, Object... args) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createFallback() { - return null; - } - - protected SpecializationNode createPolymorphic() { - return null; - } - - protected SpecializationNode createNext(Frame frame) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object o1) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object o1, Object o2) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3, Object o4) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - throw new UnsupportedOperationException(); - } - - protected SpecializationNode createNext(Frame frame, Object... args) { - throw new UnsupportedOperationException(); - } - - protected final Object uninitialized(Frame frame) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent0(this, "insert new specialization", frame)); - if (newNode == null) { - return unsupported(frame); - } - return newNode.acceptAndExecute(frame); - } - - protected final Object uninitialized(Frame frame, Object o1) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent1(this, "insert new specialization", frame, o1)); - if (newNode == null) { - return unsupported(frame, o1); - } - return newNode.acceptAndExecute(frame, o1); - } - - protected final Object uninitialized(Frame frame, Object o1, Object o2) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent2(this, "insert new specialization", frame, o1, o2)); - if (newNode == null) { - return unsupported(frame, o1, o2); - } - return newNode.acceptAndExecute(frame, o1, o2); - } - - protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent3(this, "insert new specialization", frame, o1, o2, o3)); - if (newNode == null) { - return unsupported(frame, o1, o2, o3); - } - return newNode.acceptAndExecute(frame, o1, o2, o3); - } - - protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent4(this, "insert new specialization", frame, o1, o2, o3, o4)); - if (newNode == null) { - return unsupported(frame, o1, o2, o3, o4); - } - return newNode.acceptAndExecute(frame, o1, o2, o3, o4); - } - - protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEvent5(this, "insert new specialization", frame, o1, o2, o3, o4, o5)); - if (newNode == null) { - return unsupported(frame, o1, o2, o3, o4, o5); - } - return newNode.acceptAndExecute(frame, o1, o2, o3, o4, o5); - } - - protected final Object uninitialized(Frame frame, Object... args) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - SpecializationNode newNode = atomic(new InsertionEventN(this, "insert new specialization", frame, args)); - if (newNode == null) { - return unsupported(frame, args); - } - return newNode.acceptAndExecute(frame, args); - } - - protected final Object remove(String reason, Frame frame) { - return atomic(new RemoveEvent0(this, reason, frame)).acceptAndExecute(frame); - } - - protected final Object remove(String reason, Frame frame, Object o1) { - return atomic(new RemoveEvent1(this, reason, frame, o1)).acceptAndExecute(frame, o1); - } - - protected final Object remove(String reason, Frame frame, Object o1, Object o2) { - return atomic(new RemoveEvent2(this, reason, frame, o1, o2)).acceptAndExecute(frame, o1, o2); - } - - protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3) { - return atomic(new RemoveEvent3(this, reason, frame, o1, o2, o3)).acceptAndExecute(frame, o1, o2, o3); - } - - protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - return atomic(new RemoveEvent4(this, reason, frame, o1, o2, o3, o4)).acceptAndExecute(frame, o1, o2, o3, o4); - } - - protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - return atomic(new RemoveEvent5(this, reason, frame, o1, o2, o3, o4, o5)).acceptAndExecute(frame, o1, o2, o3, o4, o5); - } - - protected final Object remove(String reason, Frame frame, Object... args) { - return atomic(new RemoveEventN(this, reason, frame, args)).acceptAndExecute(frame, args); - } - - protected Object unsupported(Frame frame) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren()); - } - - protected Object unsupported(Frame frame, Object o1) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1); - } - - protected Object unsupported(Frame frame, Object o1, Object o2) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2); - } - - protected Object unsupported(Frame frame, Object o1, Object o2, Object o3) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3); - } - - protected Object unsupported(Frame frame, Object o1, Object o2, Object o3, Object o4) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3, o4); - } - - protected Object unsupported(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3, o4, o5); - } - - protected Object unsupported(Frame frame, Object... args) { - throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), args); - } - - static SpecializationNode insertSorted(SpecializationNode start, final SpecializationNode generated, final CharSequence message, final SpecializationNode merged) { - if (merged == generated) { - // new node - if (start.count() == 2) { - SpecializationNode polymorphic = start.createPolymorphic(); - /* - * For nodes with all parameters evaluated in the execute method we do not need a - * polymorphic node. the generated code returns null in createPolymorphic in this - * case. - */ - if (polymorphic != null) { - insertAt(start, polymorphic, "insert polymorphic"); - } - } - SpecializationNode current = start; - while (current != null && current.index < generated.index) { - current = current.next; - } - return insertAt(current, generated, message); - } else { - // existing node - return start; - } - } - - static SpecializationNode insertAt(SpecializationNode node, SpecializationNode insertBefore, CharSequence reason) { - insertBefore.next = node; - // always guaranteed to be executed inside of an atomic block - return NodeUtil.nonAtomicReplace(node, insertBefore, reason); - } - - @Override - public final String toString() { - Class clazz = getClass(); - StringBuilder b = new StringBuilder(); - b.append(clazz.getSimpleName()); - - appendFields(b, clazz); - if (next != null) { - b.append("\n -> ").append(next.toString()); - } - return b.toString(); - } - - private void appendFields(StringBuilder b, Class clazz) { - Field[] fields = clazz.getDeclaredFields(); - if (fields.length == 0) { - return; - } - b.append("("); - String sep = ""; - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers())) { - continue; - } - b.append(sep); - String name = field.getName(); - if (name.equals("root")) { - continue; - } - b.append(field.getName()); - b.append(" = "); - try { - field.setAccessible(true); - Object value = field.get(this); - if (value instanceof Object[]) { - b.append(Arrays.toString((Object[]) field.get(this))); - } else { - b.append(field.get(this)); - } - } catch (IllegalArgumentException e) { - b.append(e.toString()); - } catch (IllegalAccessException e) { - b.append(e.toString()); - } - sep = ", "; - } - b.append(")"); - } - - protected static void check(Assumption assumption) throws InvalidAssumptionException { - if (assumption != null) { - assumption.check(); - } - } - - @ExplodeLoop - protected static void check(Assumption[] assumptions) throws InvalidAssumptionException { - if (assumptions != null) { - CompilerAsserts.compilationConstant(assumptions.length); - for (Assumption assumption : assumptions) { - check(assumption); - } - } - } - - protected static boolean isValid(Assumption assumption) { - if (assumption != null) { - return assumption.isValid(); - } - return true; - } - - protected static boolean isValid(Assumption[] assumptions) { - if (assumptions != null) { - for (Assumption assumption : assumptions) { - if (!isValid(assumption)) { - return false; - } - } - } - return true; - } - - private static final class InsertionEvent0 extends SlowPathEvent0 implements Callable { - - public InsertionEvent0(SpecializationNode source, String reason, Frame frame) { - super(source, reason, frame); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame)); - } - } - - } - - private static final class InsertionEvent1 extends SlowPathEvent1 implements Callable { - - public InsertionEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { - super(source, reason, frame, o1); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, o1); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, o1)); - } - } - - } - - private static final class InsertionEvent2 extends SlowPathEvent2 implements Callable { - - public InsertionEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { - super(source, reason, frame, o1, o2); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, o1, o2); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, o1, o2)); - } - } - - } - - private static final class InsertionEvent3 extends SlowPathEvent3 implements Callable { - - public InsertionEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { - super(source, reason, frame, o1, o2, o3); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, o1, o2, o3); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3)); - } - } - - } - - private static final class InsertionEvent4 extends SlowPathEvent4 implements Callable { - - public InsertionEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - super(source, reason, frame, o1, o2, o3, o4); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, o1, o2, o3, o4); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4)); - } - } - - } - - private static final class InsertionEvent5 extends SlowPathEvent5 implements Callable { - - public InsertionEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - super(source, reason, frame, o1, o2, o3, o4, o5); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, o1, o2, o3, o4, o5); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4, o5)); - } - } - - } - - private static final class InsertionEventN extends SlowPathEventN implements Callable { - - public InsertionEventN(SpecializationNode source, String reason, Frame frame, Object[] args) { - super(source, reason, frame, args); - } - - public SpecializationNode call() throws Exception { - SpecializationNode next = source.createNext(frame, args); - if (next == null) { - next = source.createFallback(); - } - if (next == null) { - return null; - } - SpecializationNode start = source.findStart(); - if (start.index == Integer.MAX_VALUE) { - return insertAt(start, next, this); - } else { - return insertSorted(start, next, this, start.merge(next, frame, args)); - } - } - } - - private static final class RemoveEvent0 extends SlowPathEvent0 implements Callable { - - public RemoveEvent0(SpecializationNode source, String reason, Frame frame) { - super(source, reason, frame); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEvent1 extends SlowPathEvent1 implements Callable { - - public RemoveEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { - super(source, reason, frame, o1); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEvent2 extends SlowPathEvent2 implements Callable { - - public RemoveEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { - super(source, reason, frame, o1, o2); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEvent3 extends SlowPathEvent3 implements Callable { - - public RemoveEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { - super(source, reason, frame, o1, o2, o3); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEvent4 extends SlowPathEvent4 implements Callable { - - public RemoveEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - super(source, reason, frame, o1, o2, o3, o4); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEvent5 extends SlowPathEvent5 implements Callable { - - public RemoveEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - super(source, reason, frame, o1, o2, o3, o4, o5); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - - } - - private static final class RemoveEventN extends SlowPathEventN implements Callable { - - public RemoveEventN(SpecializationNode source, String reason, Frame frame, Object[] args) { - super(source, reason, frame, args); - } - - public SpecializationNode call() throws Exception { - return source.removeSame(this); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializedNode.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializedNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.dsl.internal; - -import com.oracle.truffle.api.nodes.*; - -/** - * Implemented by DSL generated operation classes. This is internal implementation dependent API. - */ -public interface SpecializedNode extends NodeInterface { - - /** Returns the root {@link SpecializationNode} of the DSL operation. */ - SpecializationNode getSpecializationNode(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/META-INF/services/com.oracle.truffle.api.impl.SymbolInvoker --- a/graal/com.oracle.truffle.api.interop/src/META-INF/services/com.oracle.truffle.api.impl.SymbolInvoker Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.truffle.api.interop.impl.SymbolInvokerImpl diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Execute.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Execute.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class Execute extends KnownMessage { - public static final int HASH1 = 423430; - public static final int HASH2 = 423429; - - private final int arity; - private final boolean invoke; - - public static Execute create(boolean invoke, int arity) { - return new Execute(invoke, arity); - } - - private Execute(boolean invoke, int arity) { - this.invoke = invoke; - this.arity = arity; - } - - public int getArity() { - return arity; - } - - @Override - public boolean equals(Object message) { - if (!(message instanceof Execute)) { - return false; - } - Execute m1 = this; - Execute m2 = (Execute) message; - return m1.invoke == m2.invoke; - } - - @Override - public int hashCode() { - return invoke ? HASH1 : HASH2; - } - - @Override - public String toString() { - return invoke ? "msgInvoke" : "msgExecute"; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.impl.ReadOnlyArrayList; -import com.oracle.truffle.api.nodes.Node; -import java.util.List; - -/** - * Encapsulates types of access to {@link TruffleObject}. If you want to expose your own objects to - * foreign language implementations, you need to implement {@link TruffleObject} and its - * {@link TruffleObject#getForeignAccess()} method. To create instance of ForeignAccess - * , use one of the factory methods available in this class. - */ -public final class ForeignAccess { - private final Factory factory; - - private ForeignAccess(Factory faf) { - this.factory = faf; - } - - /** - * Creates new instance of {@link ForeignAccess} that delegates to provided factory. - * - * @param baseClass the super class of all {@link TruffleObject}s handled by this factory (if - * null than the second interface also needs to implement - * {@link Factory}) - * @param factory the factory that handles access requests to {@link Message}s known as of - * version 1.0 - * @return new instance wrapping factory - */ - public static ForeignAccess create(final Class baseClass, final Factory10 factory) { - if (baseClass == null) { - Factory f = (Factory) factory; - assert f != null; - } - class DelegatingFactory implements Factory { - @Override - public boolean canHandle(TruffleObject obj) { - if (baseClass == null) { - return ((Factory) factory).canHandle(obj); - } - return baseClass.isInstance(obj); - } - - @Override - public CallTarget accessMessage(Message msg) { - if (msg instanceof KnownMessage) { - switch (msg.hashCode()) { - case Execute.HASH1: - return factory.accessInvoke(((Execute) msg).getArity()); - case Execute.HASH2: - return factory.accessExecute(((Execute) msg).getArity()); - case GetSize.HASH: - return factory.accessGetSize(); - case HasSize.HASH: - return factory.accessHasSize(); - case IsBoxed.HASH: - return factory.accessIsBoxed(); - case IsExecutable.HASH: - return factory.accessIsExecutable(); - case IsNull.HASH: - return factory.accessIsNull(); - case Read.HASH: - return factory.accessRead(); - case Unbox.HASH: - return factory.accessUnbox(); - case Write.HASH: - return factory.accessWrite(); - } - } - return factory.accessMessage(msg); - } - } - return new ForeignAccess(new DelegatingFactory()); - } - - /** - * Creates new instance of {@link ForeignAccess} that delegates to provided factory. - * - * @param factory the factory that handles various access requests {@link Message}s. - * @return new instance wrapping factory - */ - public static ForeignAccess create(Factory factory) { - return new ForeignAccess(factory); - } - - /** - * Executes {@link Message#createNode() foreign node}. - * - * @param foreignNode the createNode created by {@link Message#createNode()} - * @param frame the call frame - * @param receiver foreign object to receive the message passed to {@link Message#createNode()} - * method - * @param arguments parameters for the receiver - * @return return value, if any - * @throws ClassCastException if the createNode has not been created by - * {@link Message#createNode()} method. - */ - public static Object execute(Node foreignNode, VirtualFrame frame, TruffleObject receiver, Object... arguments) { - ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) foreignNode; - return fn.executeForeign(frame, receiver, arguments); - } - - /** - * Read only access to foreign call arguments inside of a frame. - * - * @param frame the frame that was called via - * {@link #execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) } - * @return read-only list of parameters passed to the frame - */ - public static List getArguments(Frame frame) { - final Object[] arr = frame.getArguments(); - return ReadOnlyArrayList.asList(arr, 1, arr.length); - } - - /** - * The foreign receiver in the frame. - * - * @param frame the frame that was called via - * {@link #execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) } - * @return the receiver used when invoking the frame - */ - public static TruffleObject getReceiver(Frame frame) { - return (TruffleObject) frame.getArguments()[ForeignAccessArguments.RECEIVER_INDEX]; - } - - CallTarget access(Message message) { - return factory.accessMessage(message); - } - - boolean canHandle(TruffleObject receiver) { - return factory.canHandle(receiver); - } - - /** - * Interface of a factory that produces AST snippets that can access a foreign - * {@code TruffleObject}. A Truffle language implementation accesses a {@code TruffleObject} via - * a {@code Message}. The {@code TruffleObject} instance provides a {@link ForeignAccess} - * instance (built via {@link #create(com.oracle.truffle.api.interop.ForeignAccess.Factory)}) - * that provides an AST snippet for a given {@link Message}. Rather than using this generic - * {@code Factory}, consider implementing {@link Factory10} interface that captures the set of - * messages each language should implement as of Truffle version 1.0. - */ - public interface Factory { - - /** - * * Checks whether provided {@link TruffleObject} can be accessed using AST snippets - * produced by this {@link Factory}. - * - * @param obj the object to check - * @return true, if the object can be processed - */ - boolean canHandle(TruffleObject obj); - - /** - * Provides an AST snippet to access a {@code TruffleObject}. - * - * @param tree the {@code Message} that represents the access to a {@code TruffleObject}. - * @return the AST snippet for accessing the {@code TruffleObject}, wrapped as a - * {@code CallTarget}. - */ - CallTarget accessMessage(Message tree); - } - - /** - * Specialized {@link Factory factory} that handles {@link Message messages} known as of release - * 1.0 of Truffle API. - * - */ - public interface Factory10 { - /** - * Handles {@link Message#IS_NULL} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessIsNull(); - - /** - * Handles {@link Message#IS_EXECUTABLE} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessIsExecutable(); - - /** - * Handles {@link Message#IS_BOXED} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessIsBoxed(); - - /** - * Handles {@link Message#HAS_SIZE} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessHasSize(); - - /** - * Handles {@link Message#GET_SIZE} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessGetSize(); - - /** - * Handles {@link Message#UNBOX} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessUnbox(); - - /** - * Handles {@link Message#READ} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessRead(); - - /** - * Handles {@link Message#WRITE} message. - * - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessWrite(); - - /** - * Handles {@link Message#createExecute(int)} messages. - * - * @param argumentsLength number of parameters the messages has been created for - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessExecute(int argumentsLength); - - /** - * Handles {@link Message#createInvoke(int)} messages. - * - * @param argumentsLength number of parameters the messages has been created for - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessInvoke(int argumentsLength); - - /** - * Handles request for access to a message not known in version 1.0. - * - * @param unknown the message - * @return call target to handle the message or null if this message is not - * supported - */ - CallTarget accessMessage(Message unknown); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccessArguments.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccessArguments.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class ForeignAccessArguments { - static final Object[] EMPTY_ARGUMENTS_ARRAY = new Object[0]; - static final int RECEIVER_INDEX = 0; - static final int RUNTIME_ARGUMENT_COUNT = 1; - - static Object[] create(Object receiver, Object... arguments) { - if (arguments.length == 0) { - return new Object[]{receiver}; - } - Object[] objectArguments = new Object[RUNTIME_ARGUMENT_COUNT + arguments.length]; - objectArguments[RECEIVER_INDEX] = receiver; - arraycopy(arguments, 0, objectArguments, RUNTIME_ARGUMENT_COUNT, arguments.length); - return objectArguments; - } - - private static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { - for (int i = 0; i < length; i++) { - dest[destPos + i] = src[srcPos + i]; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; -import com.oracle.truffle.api.nodes.Node; - -final class ForeignObjectAccessHeadNode extends Node { - - @Child private ObjectAccessNode first; - private final Message accessTree; - - protected ForeignObjectAccessHeadNode(Message tree) { - this.accessTree = tree; - this.first = new UnresolvedObjectAccessNode(); - adoptChildren(); - } - - protected Message getAccessTree() { - return accessTree; - } - - protected ObjectAccessNode getFirst() { - return first; - } - - public Object executeForeign(VirtualFrame frame, TruffleObject receiver, Object... arguments) { - return first.executeWith(frame, receiver, arguments); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/GetSize.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/GetSize.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class GetSize extends UnaryMessage { - public static final int HASH = 423432; - - static Message INSTANCE = new GetSize(); - - @Override - public String toString() { - return "msgGetSize"; - } - - @Override - public int hashCode() { - return HASH; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/HasSize.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/HasSize.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class HasSize extends UnaryMessage { - public static final int HASH = 423433; - static Message INSTANCE = new HasSize(); - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgHasSize"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsBoxed.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsBoxed.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class IsBoxed extends UnaryMessage { - public static final int HASH = 423434; - static Message INSTANCE = new IsBoxed(); - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgIsBoxed"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsExecutable.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsExecutable.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class IsExecutable extends UnaryMessage { - public static final int HASH = 423435; - static Message INSTANCE = new IsExecutable(); - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgIsExecutable"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsNull.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/IsNull.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class IsNull extends UnaryMessage { - public static final int HASH = 423436; - static Message INSTANCE = new IsNull(); - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgIsNull"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/KnownMessage.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/KnownMessage.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Marker class. - */ -abstract class KnownMessage extends Message { -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.Node; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; - -/** - * Inter-operability is based on sending messages. Standard messages are defined as as constants - * like {@link #IS_NULL} or factory methods in this class, but one can always define their own, - * specialized messages. - */ -public abstract class Message { - /** - * Message to read a field. - */ - public static final Message READ = Read.INSTANCE; - - /** - * Converts {@link TruffleObject truffle value} to Java primitive type. Primitive types are - * subclasses of {@link Number}, {@link Boolean}, {@link Character} and {@link String}. Related - * to {@link #IS_BOXED} message. - */ - public static final Message UNBOX = Unbox.INSTANCE; - - /** - * Message to write a field. - */ - public static Message WRITE = Write.INSTANCE; - - /** - * Creates an execute message. All messages created by this method are - * {@link Object#equals(java.lang.Object) equal} to each other regardless of the value of - * argumentsLength. - * - * @param argumentsLength number of parameters to pass to the target - * @return execute message - */ - public static Message createExecute(int argumentsLength) { - return Execute.create(false, argumentsLength); - } - - /** - * Message to check for executability. - *

- * Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for - * this message should yield value of {@link Boolean}. - */ - public static final Message IS_EXECUTABLE = IsExecutable.INSTANCE; - - /** - * Creates an execute message. All messages created by this method are - * {@link Object#equals(java.lang.Object) equal} to each other regardless of the value of - * argumentsLength. The expected behavior of this message is to perform - * {@link #READ} first and on the result invoke {@link #createExecute(int)}. - * - * @param argumentsLength number of parameters to pass to the target - * @return read & execute message - */ - public static Message createInvoke(int argumentsLength) { - return Execute.create(true, argumentsLength); - } - - /** - * Check for null message. The Truffle languages are suggested to have their own - * object representing null like values in their languages. For purposes of - * inter-operability it is essential to canonicalize such values from time to time - sending - * this message is a way to recognize such null representing values. - *

- * Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for - * this message should yield value of {@link Boolean}. - */ - public static final Message IS_NULL = IsNull.INSTANCE; - - /** - * Message to check for having a size. - *

- * Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for - * this message should yield value of {@link Boolean}. - */ - public static final Message HAS_SIZE = HasSize.INSTANCE; - - /** - * Getter of the size. If {@link #HAS_SIZE supported}, this message allows to obtain a size (of - * an array). - *

- * Calling {@link Factory#access(com.oracle.truffle.api.interop.Message) the target} created for - * this message should yield value of {@link Integer}. - */ - public static final Message GET_SIZE = GetSize.INSTANCE; - - /** - * Check for value being boxed. Can you value be converted to one of the basic Java types? Many - * languages have a special representation for types like number, string, etc. To ensure - * inter-operability, these types should support unboxing - if they do, they should handle this - * message. - *

- * Calling {@link Factory#accessMessage(com.oracle.truffle.api.interop.Message) the target} - * created for this message should yield value of {@link Boolean}. - */ - public static final Message IS_BOXED = IsBoxed.INSTANCE; - - /** - * Compares types of two messages. Messages are encouraged to implement this method. All - * standard ones ({@link #IS_NULL}, {@link #READ}, etc.) do so. Messages obtained via the same - * {@link #createExecute(int) method} are equal, messages obtained by different methods or - * fields are not. - * - * @param message the object to compare to - * @return true, if the structure of the message is that same as of this one. - */ - @Override - public abstract boolean equals(Object message); - - /** - * When re-implementing {@link #equals(java.lang.Object)}, it is generally recommended to also - * implement hashCode(). - * - * @return hash code - */ - @Override - public abstract int hashCode(); - - /** - * Creates an AST node for this message. The node can be inserted into AST of your language and - * will handle communication with the foreign language. - * - * @return node to be inserted into your AST and passed back to - * {@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object[])} - * method. - */ - public final Node createNode() { - return new ForeignObjectAccessHeadNode(this); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ObjectAccessNode.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ObjectAccessNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -abstract class ObjectAccessNode extends Node { - - public abstract Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments); - -} - -class UnresolvedObjectAccessNode extends ObjectAccessNode { - - private static final int CACHE_SIZE = 8; - private int cacheLength = 1; - - @Override - public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - ForeignObjectAccessHeadNode nthParent = (ForeignObjectAccessHeadNode) NodeUtil.getNthParent(this, cacheLength); - ObjectAccessNode first = nthParent.getFirst(); - if (cacheLength < CACHE_SIZE) { - cacheLength++; - CachedObjectAccessNode createCachedAccess = createCachedAccess(receiver, nthParent.getAccessTree(), first); - return first.replace(createCachedAccess).executeWith(frame, receiver, arguments); - } else { - return first.replace(createGenericAccess(nthParent.getAccessTree())).executeWith(frame, receiver, arguments); - } - } - - private static CachedObjectAccessNode createCachedAccess(TruffleObject receiver, Message accessTree, ObjectAccessNode next) { - ForeignAccess fa = receiver.getForeignAccess(); - final CallTarget ct = fa.access(accessTree); - if (ct == null) { - throw new IllegalArgumentException("Message " + accessTree + " not recognized by " + fa); - } - return new CachedObjectAccessNode(Truffle.getRuntime().createDirectCallNode(ct), next, fa); - } - - private static GenericObjectAccessNode createGenericAccess(Message access) { - return new GenericObjectAccessNode(access); - } -} - -class GenericObjectAccessNode extends ObjectAccessNode { - - private final Message access; - @Child private IndirectCallNode indirectCallNode; - - public GenericObjectAccessNode(Message access) { - this.access = access; - indirectCallNode = Truffle.getRuntime().createIndirectCallNode(); - } - - public GenericObjectAccessNode(GenericObjectAccessNode prev) { - this(prev.access); - } - - @Override - public Object executeWith(VirtualFrame frame, TruffleObject truffleObject, Object[] arguments) { - final ForeignAccess fa = truffleObject.getForeignAccess(); - final CallTarget ct = fa.access(access); - if (ct == null) { - throw new IllegalStateException("Message " + access + " not recognized by " + fa); - } - return indirectCallNode.call(frame, ct, ForeignAccessArguments.create(truffleObject, arguments)); - } -} - -class CachedObjectAccessNode extends ObjectAccessNode { - @Child private DirectCallNode callTarget; - @Child private ObjectAccessNode next; - - private final ForeignAccess languageCheck; - - protected CachedObjectAccessNode(DirectCallNode callTarget, ObjectAccessNode next, ForeignAccess languageCheck) { - this.callTarget = callTarget; - this.next = next; - this.languageCheck = languageCheck; - this.callTarget.forceInlining(); - } - - protected CachedObjectAccessNode(CachedObjectAccessNode prev) { - this(prev.callTarget, prev.next, prev.languageCheck); - } - - @Override - public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - return doAccess(frame, receiver, arguments); - } - - private Object doAccess(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - if (languageCheck.canHandle(receiver)) { - return callTarget.call(frame, ForeignAccessArguments.create(receiver, arguments)); - } else { - return doNext(frame, receiver, arguments); - } - } - - private Object doNext(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { - return next.executeWith(frame, receiver, arguments); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Read.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Read.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class Read extends KnownMessage { - public static final int HASH = 423438; - static Message INSTANCE = new Read(); - - private Read() { - } - - @Override - public boolean equals(Object message) { - return message instanceof Read; - } - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgRead"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/TruffleObject.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/TruffleObject.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Interface for any entity of a Truffle guest language implementations that can be shared across - * other language implementations. - */ -public interface TruffleObject { - /** - * Provides the {@code ForeignAccessFactory} instance for this {@code TruffleObject} instance. - * - * @return the {@code ForeignAccessFactory} instance for this {@code TruffleObject} instance. - */ - ForeignAccess getForeignAccess(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnaryMessage.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnaryMessage.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -abstract class UnaryMessage extends KnownMessage { - protected UnaryMessage() { - } - - @Override - public boolean equals(Object message) { - if (message == null) { - return false; - } - return this.getClass() == message.getClass(); - } - - @Override - public abstract int hashCode(); - - @Override - public abstract String toString(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Unbox.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Unbox.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class Unbox extends UnaryMessage { - public static final int HASH = 423437; - static Message INSTANCE = new Unbox(); - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgUnbox"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Write.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Write.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -final class Write extends KnownMessage { - public static final int HASH = 423431; - - static Message INSTANCE = new Write(); - - @Override - public boolean equals(Object message) { - return message instanceof Write; - } - - @Override - public int hashCode() { - return HASH; - } - - @Override - public String toString() { - return "msgWrite"; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/ReadOnlyArrayList.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/ReadOnlyArrayList.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; - -public final class ReadOnlyArrayList implements List { - private final T[] arr; - private final int first; - private final int last; - - private ReadOnlyArrayList(T[] arr, int first, int last) { - this.arr = arr; - this.first = first; - this.last = last; - } - - public static List asList(T[] arr, int first, int last) { - return new ReadOnlyArrayList<>(arr, first, last); - } - - @Override - public int size() { - return last - first; - } - - @Override - public boolean isEmpty() { - return first == last; - } - - @Override - public boolean contains(Object o) { - for (int i = first; i < last; i++) { - if (o == arr[i] || (o != null && o.equals(arr[i]))) { - return true; - } - } - return false; - } - - @Override - public Iterator iterator() { - return new LI(first); - } - - @Override - public Object[] toArray() { - return toArray(new Object[size()]); - } - - @Override - @SuppressWarnings("unchecked") - public A[] toArray(A[] b) { - A[] a; - if (b.length < size()) { - a = (A[]) Array.newInstance(b.getClass().getComponentType(), size()); - } else { - a = b; - } - for (int i = 0, at = first; at < last; i++, at++) { - a[i] = (A) arr[at]; - } - return a; - } - - @Override - public boolean add(Object e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - for (Object obj : c) { - if (!contains(obj)) { - return false; - } - } - return true; - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public T get(int index) { - int at = first + index; - T ret = arr[at]; - if (at >= last) { - throw new ArrayIndexOutOfBoundsException(); - } - return ret; - } - - @Override - public T set(int index, Object element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, Object element) { - throw new UnsupportedOperationException(); - } - - @Override - public T remove(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public int indexOf(Object o) { - for (int i = first; i < last; i++) { - if (arr[i] == null) { - if (o == null) { - return i - first; - } - } else { - if (arr[i].equals(o)) { - return i - first; - } - } - } - return -1; - } - - @Override - public int lastIndexOf(Object o) { - for (int i = last - 1; i >= first; i--) { - if (arr[i] == null) { - if (o == null) { - return i - first; - } - } else { - if (arr[i].equals(o)) { - return i - first; - } - } - } - return -1; - } - - @Override - public ListIterator listIterator() { - return new LI(first); - } - - @Override - public ListIterator listIterator(int index) { - return new LI(first + index); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return new ReadOnlyArrayList<>(arr, first + fromIndex, first + toIndex); - } - - private final class LI implements ListIterator, Iterator { - private int index; - - public LI(int index) { - this.index = index; - } - - @Override - public boolean hasNext() { - return index < last; - } - - @Override - public T next() { - if (index >= last) { - throw new NoSuchElementException(); - } - return arr[index++]; - } - - @Override - public boolean hasPrevious() { - return index > first; - } - - @Override - public T previous() { - if (first == index) { - throw new NoSuchElementException(); - } - return arr[--index]; - } - - @Override - public int nextIndex() { - return index - first; - } - - @Override - public int previousIndex() { - return index - 1 - first; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void set(Object e) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(Object e) { - throw new UnsupportedOperationException(); - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; -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.*; - -public final class SymbolInvokerImpl extends SymbolInvoker { - static final FrameDescriptor UNUSED_FRAMEDESCRIPTOR = new FrameDescriptor(); - - @Override - protected Object invoke(Object symbol, Object... arr) throws IOException { - if (symbol instanceof String) { - return symbol; - } - if (symbol instanceof Number) { - return symbol; - } - if (symbol instanceof Boolean) { - return symbol; - } - Node executeMain = Message.createExecute(arr.length).createNode(); - CallTarget callTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(executeMain, (TruffleObject) symbol, arr)); - VirtualFrame frame = Truffle.getRuntime().createVirtualFrame(arr, UNUSED_FRAMEDESCRIPTOR); - Object ret = callTarget.call(frame); - if (ret instanceof TruffleObject) { - TruffleObject tret = (TruffleObject) ret; - Object isBoxedResult; - try { - Node isBoxed = Message.IS_BOXED.createNode(); - CallTarget isBoxedTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(isBoxed, tret)); - isBoxedResult = isBoxedTarget.call(frame); - } catch (IllegalArgumentException ex) { - isBoxedResult = false; - } - if (Boolean.TRUE.equals(isBoxedResult)) { - Node unbox = Message.UNBOX.createNode(); - CallTarget unboxTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(unbox, tret)); - Object unboxResult = unboxTarget.call(frame); - return unboxResult; - } else { - try { - Node isNull = Message.IS_NULL.createNode(); - CallTarget isNullTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(isNull, tret)); - Object isNullResult = isNullTarget.call(frame); - if (Boolean.TRUE.equals(isNullResult)) { - return null; - } - } catch (IllegalArgumentException ex) { - // fallthrough - } - } - } - return ret; - } - - private static class TemporaryRoot extends RootNode { - @Child private Node foreignAccess; - private final TruffleObject function; - private final Object[] args; - - public TemporaryRoot(Node foreignAccess, TruffleObject function, Object... args) { - this.foreignAccess = foreignAccess; - this.function = function; - this.args = args; - } - - @Override - public Object execute(VirtualFrame frame) { - return ForeignAccess.execute(foreignAccess, frame, function, args); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/package-info.java --- a/graal/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/package-info.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -/** - * This package provides inter-operability between different - * {@link com.oracle.truffle.api.TruffleLanguage Truffle languages}. - *

- * Languages can exchange primitive Java type wrapper objects (e.g., {@link java.lang.Integer}, - * {@link java.lang.Double}, {@link java.lang.String}, etc) as well as any type - * implementing {@link com.oracle.truffle.api.interop.TruffleObject}. Foreign objects are - * precisely those implementing {@link com.oracle.truffle.api.interop.TruffleObject}. - *

- * To use a {@link com.oracle.truffle.api.interop.TruffleObject} from a different language, - * you need to ask the language to build appropriate AST for a given - * {@link com.oracle.truffle.api.interop.Message} with - * {@link com.oracle.truffle.api.interop.Message#createNode}. The message can then - * be executed with {@link com.oracle.truffle.api.interop.ForeignAccess#execute}. - */ -package com.oracle.truffle.api.interop; - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/BaseLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/BaseLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface BaseLocation { - /** - * Get object value as object at this location in store. - * - * @param shape the current shape of the object, which must contain this location - */ - Object get(DynamicObject store, Shape shape); - - /** - * Get object value as object at this location in store. For internal use only and subject to - * change, use {@link #get(DynamicObject, Shape)} instead. - * - * @param condition the result of a shape check or {@code false} - * @see #get(DynamicObject, Shape) - */ - Object get(DynamicObject store, boolean condition); - - /** - * Set object value at this location in store. - * - * @throws IncompatibleLocationException for storage type invalidations - * @throws FinalLocationException for effectively final fields - */ - void set(DynamicObject store, Object value) throws IncompatibleLocationException, FinalLocationException; - - /** - * Set object value at this location in store. - * - * @param shape the current shape of the storage object - * @throws IncompatibleLocationException for storage type invalidations - * @throws FinalLocationException for effectively final fields - */ - void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException; - - /** - * Set object value at this location in store and update shape. - * - * @param oldShape the shape before the transition - * @param newShape new shape after the transition - * @throws IncompatibleLocationException if value is of non-assignable type - */ - void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/BooleanLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/BooleanLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface BooleanLocation extends TypedLocation { - /** - * @see #get(DynamicObject, Shape) - */ - boolean getBoolean(DynamicObject store, Shape shape); - - /** - * @see #get(DynamicObject, boolean) - */ - boolean getBoolean(DynamicObject store, boolean condition); - - /** - * @see #set(DynamicObject, Object) - */ - void setBoolean(DynamicObject store, boolean value) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape) - */ - void setBoolean(DynamicObject store, boolean value, Shape shape) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape, Shape) - */ - void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape); - - Class getType(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DebugCounter.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DebugCounter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import java.io.*; -import java.util.*; -import java.util.concurrent.atomic.*; - -public final class DebugCounter { - private static final ArrayList allCounters = new ArrayList<>(); - - private final String name; - private final AtomicLong value; - - private DebugCounter(String name) { - this.name = name; - this.value = new AtomicLong(); - allCounters.add(this); - } - - public static DebugCounter create(String name) { - return new DebugCounter(name); - } - - public long get() { - return value.get(); - } - - public void inc() { - value.incrementAndGet(); - } - - @Override - public String toString() { - return name + ": " + value; - } - - public static void dumpCounters() { - dumpCounters(System.out); - } - - public static void dumpCounters(PrintStream out) { - for (DebugCounter counter : allCounters) { - out.println(counter); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DoubleLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DoubleLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface DoubleLocation extends TypedLocation { - /** - * @see #get(DynamicObject, Shape) - */ - double getDouble(DynamicObject store, Shape shape); - - /** - * @see #get(DynamicObject, boolean) - */ - double getDouble(DynamicObject store, boolean condition); - - /** - * @see #set(DynamicObject, Object) - */ - void setDouble(DynamicObject store, double value) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape) - */ - void setDouble(DynamicObject store, double value, Shape shape) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape, Shape) - */ - void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape); - - Class getType(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DynamicObject.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DynamicObject.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.interop.*; - -public abstract class DynamicObject implements TypedObject, TruffleObject { - /** - * Get the object's current shape. - */ - public abstract Shape getShape(); - - /** - * Get property value. - * - * @param key property identifier - * @param defaultValue return value if property is not found - * @return property value or defaultValue if object has no such property - */ - public abstract Object get(Object key, Object defaultValue); - - /** - * Set value of existing property. - * - * @param key property identifier - * @param value value to be set - * @return {@code true} if successful or {@code false} if property not found - */ - public abstract boolean set(Object key, Object value); - - /** - * Returns {@code true} if this object contains a property with the given key. - */ - public final boolean containsKey(Object key) { - return getShape().getProperty(key) != null; - } - - /** - * Define new property or redefine existing property. - * - * @param key property identifier - * @param value value to be set - */ - public final void define(Object key, Object value) { - define(key, value, 0); - } - - /** - * Define new property or redefine existing property. - * - * @param key property identifier - * @param value value to be set - * @param flags flags to be set - */ - public abstract void define(Object key, Object value, int flags); - - /** - * Define new property with a static location or change existing property. - * - * @param key property identifier - * @param value value to be set - * @param flags flags to be set - * @param locationFactory factory function that creates a location for a given shape and value - */ - public abstract void define(Object key, Object value, int flags, LocationFactory locationFactory); - - /** - * Change property flags. - * - * @param key property identifier - * @param newFlags flags to be set - * @return {@code true} if successful or {@code false} if property not found - */ - public abstract boolean changeFlags(Object key, int newFlags); - - /** - * Change property flags. - * - * @param key property identifier - * @param flagsUpdateFunction function updating old flags to new flags - * @return {@code true} if successful or {@code false} if property not found - */ - public abstract boolean changeFlags(Object key, FlagsFunction flagsUpdateFunction); - - /** - * Delete property. - * - * @param key property identifier - * @return {@code true} if successful or {@code false} if property not found - */ - public abstract boolean delete(Object key); - - /** - * Returns the number of properties in this object. - */ - public abstract int size(); - - /** - * Returns {@code true} if this object contains no properties. - */ - public abstract boolean isEmpty(); - - /** - * Set object shape and grow storage if necessary. - * - * @param oldShape the object's current shape (must equal {@link #getShape()}) - * @param newShape the new shape to be set - */ - public abstract void setShapeAndGrow(Shape oldShape, Shape newShape); - - /** - * Set object shape and resize storage if necessary. - * - * @param oldShape the object's current shape (must equal {@link #getShape()}) - * @param newShape the new shape to be set - */ - public abstract void setShapeAndResize(Shape oldShape, Shape newShape); - - /** - * Ensure object shape is up-to-date. - * - * @return {@code true} if shape has changed - */ - public abstract boolean updateShape(); - - public interface FlagsFunction { - int apply(int t); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DynamicObjectFactory.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DynamicObjectFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface DynamicObjectFactory { - DynamicObject newInstance(Object... initialValues); - - Shape getShape(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/FinalLocationException.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/FinalLocationException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import com.oracle.truffle.api.nodes.*; - -public final class FinalLocationException extends SlowPathException { - private static final long serialVersionUID = -30188494510914293L; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/HiddenKey.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/HiddenKey.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public final class HiddenKey { - private final String name; - - public HiddenKey(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/IncompatibleLocationException.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/IncompatibleLocationException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import com.oracle.truffle.api.nodes.*; - -public final class IncompatibleLocationException extends SlowPathException { - private static final long serialVersionUID = -7734865392357341789L; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/IntLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/IntLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface IntLocation extends TypedLocation { - /** - * @see #get(DynamicObject, Shape) - */ - int getInt(DynamicObject store, Shape shape); - - /** - * @see #get(DynamicObject, boolean) - */ - int getInt(DynamicObject store, boolean condition); - - /** - * @see #set(DynamicObject, Object) - */ - void setInt(DynamicObject store, int value) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape) - */ - void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape, Shape) - */ - void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape); - - Class getType(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Layout.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Layout.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import java.util.*; - -import com.oracle.truffle.api.nodes.NodeUtil.FieldOffsetProvider; -import com.oracle.truffle.api.object.Shape.Allocator; - -public abstract class Layout { - public static final EnumSet NONE = EnumSet.noneOf(ImplicitCast.class); - public static final EnumSet INT_TO_DOUBLE = EnumSet.of(ImplicitCast.IntToDouble); - public static final EnumSet INT_TO_LONG = EnumSet.of(ImplicitCast.IntToLong); - - public static final String OPTION_PREFIX = "truffle.object."; - - private static final LayoutFactory LAYOUT_FACTORY = loadLayoutFactory(); - - public enum ImplicitCast { - IntToDouble, - IntToLong, - } - - public static Layout createLayout() { - return createLayout(NONE); - } - - public static Layout createLayout(EnumSet allowedImplicitCasts) { - return new LayoutBuilder().setAllowedImplicitCasts(allowedImplicitCasts).build(); - } - - public static Layout createLayout(EnumSet allowedImplicitCasts, FieldOffsetProvider fieldOffsetProvider) { - return new LayoutBuilder().setAllowedImplicitCasts(allowedImplicitCasts).setFieldOffsetProvider(fieldOffsetProvider).build(); - } - - public abstract DynamicObject newInstance(Shape shape); - - public abstract Class getType(); - - public abstract Shape createShape(ObjectType operations); - - public abstract Shape createShape(ObjectType operations, Object sharedData); - - public abstract Shape createShape(ObjectType operations, Object sharedData, int id); - - /** - * Create an allocator for static property creation. Reserves all array extension slots. - */ - public abstract Allocator createAllocator(); - - protected static LayoutFactory getFactory() { - return LAYOUT_FACTORY; - } - - private static LayoutFactory loadLayoutFactory() { - LayoutFactory bestLayoutFactory = null; - - String layoutFactoryImplClassName = System.getProperty(OPTION_PREFIX + "LayoutFactory"); - if (layoutFactoryImplClassName != null) { - Class clazz; - try { - clazz = Class.forName(layoutFactoryImplClassName); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - try { - bestLayoutFactory = (LayoutFactory) clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new AssertionError(e); - } - } else { - ServiceLoader serviceLoader = ServiceLoader.load(LayoutFactory.class, Layout.class.getClassLoader()); - for (LayoutFactory currentLayoutFactory : serviceLoader) { - if (bestLayoutFactory == null) { - bestLayoutFactory = currentLayoutFactory; - } else if (currentLayoutFactory.getPriority() >= bestLayoutFactory.getPriority()) { - assert currentLayoutFactory.getPriority() != bestLayoutFactory.getPriority(); - bestLayoutFactory = currentLayoutFactory; - } - } - } - - if (bestLayoutFactory == null) { - throw new AssertionError("LayoutFactory not found"); - } - return bestLayoutFactory; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LayoutBuilder.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LayoutBuilder.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import java.util.*; - -import com.oracle.truffle.api.nodes.NodeUtil.FieldOffsetProvider; -import com.oracle.truffle.api.object.Layout.ImplicitCast; - -public class LayoutBuilder { - private EnumSet allowedImplicitCasts; - private FieldOffsetProvider fieldOffsetProvider; - - public LayoutBuilder() { - this.allowedImplicitCasts = Layout.NONE; - this.fieldOffsetProvider = null; - } - - public Layout build() { - return Layout.getFactory().createLayout(this); - } - - public LayoutBuilder setAllowedImplicitCasts(EnumSet allowedImplicitCasts) { - this.allowedImplicitCasts = allowedImplicitCasts; - return this; - } - - public LayoutBuilder setFieldOffsetProvider(FieldOffsetProvider fieldOffsetProvider) { - this.fieldOffsetProvider = fieldOffsetProvider; - return this; - } - - public EnumSet getAllowedImplicitCasts() { - return allowedImplicitCasts; - } - - public FieldOffsetProvider getFieldOffsetProvider() { - return fieldOffsetProvider; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LayoutFactory.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LayoutFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface LayoutFactory { - Layout createLayout(LayoutBuilder layoutBuilder); - - Property createProperty(Object id, Location location); - - Property createProperty(Object id, Location location, int flags); - - int getPriority(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Location.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Location.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import com.oracle.truffle.api.*; - -/** - * Property location. - * - * @see Shape - * @see Property - * @see DynamicObject - */ -public abstract class Location implements BaseLocation { - protected static IncompatibleLocationException incompatibleLocation() throws IncompatibleLocationException { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IncompatibleLocationException(); - } - - protected static FinalLocationException finalLocation() throws FinalLocationException { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new FinalLocationException(); - } - - public final Object get(DynamicObject store, Shape shape) { - return get(store, checkShape(store, shape)); - } - - public Object get(DynamicObject store, boolean condition) { - return getInternal(store); - } - - public void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { - setInternal(store, value); - } - - public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { - if (canStore(value)) { - store.setShapeAndGrow(oldShape, newShape); - try { - setInternal(store, value); - } catch (IncompatibleLocationException ex) { - throw new IllegalStateException(); - } - } else { - throw incompatibleLocation(); - } - } - - public final void set(DynamicObject store, Object value) throws IncompatibleLocationException, FinalLocationException { - set(store, value, null); - } - - protected abstract Object getInternal(DynamicObject store); - - /** - * Like {@link #set(DynamicObject, Object, Shape)}, but does not invalidate final locations. For - * internal use only and subject to change, use {@link DynamicObjectFactory} to create objects - * with predefined properties. - * - * @throws IncompatibleLocationException if value is of non-assignable type - */ - protected abstract void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException; - - /** - * Returns {@code true} if the location can be set to the value. - * - * @param store the receiver object - * @param value the value in question - */ - public boolean canSet(DynamicObject store, Object value) { - return canStore(value); - } - - /** - * Returns {@code true} if the location is compatible with the value. - * - * The value may still be rejected if {@link #canSet(DynamicObject, Object)} returns false. - * - * @param value the value in question - */ - public boolean canStore(Object value) { - return true; - } - - /** - * Returns {@code true} if this is a final location, i.e. readonly once set. - */ - public boolean isFinal() { - return false; - } - - /** - * Returns {@code true} if this is an immutable constant location. - */ - public boolean isConstant() { - return false; - } - - /* - * Abstract to force overriding. - */ - @Override - public abstract int hashCode(); - - /* - * Abstract to force overriding. - */ - @Override - public abstract boolean equals(Object obj); - - protected static boolean checkShape(DynamicObject store, Shape shape) { - return store.getShape() == shape; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LocationFactory.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LocationFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface LocationFactory { - Location createLocation(Shape shape, Object value); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LocationModifier.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LocationModifier.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public enum LocationModifier { - Final, - NonNull, -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LongLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/LongLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface LongLocation extends TypedLocation { - /** - * @see #get(DynamicObject, Shape) - */ - long getLong(DynamicObject store, Shape shape); - - /** - * @see #get(DynamicObject, boolean) - */ - long getLong(DynamicObject store, boolean condition); - - /** - * @see #set(DynamicObject, Object) - */ - void setLong(DynamicObject store, long value) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape) - */ - void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException; - - /** - * @see #set(DynamicObject, Object, Shape, Shape) - */ - void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape); - - Class getType(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ObjectLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ObjectLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface ObjectLocation extends TypedLocation { - Class getType(); - - /** - * If {@code true}, this location does not accept {@code null} values. - */ - boolean isNonNull(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ObjectType.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ObjectType.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.*; - -public class ObjectType { - /** - * Delegate method for {@link DynamicObject#equals(Object)}. - */ - public boolean equals(DynamicObject object, Object other) { - return object == other; - } - - /** - * Delegate method for {@link DynamicObject#hashCode()}. - */ - public int hashCode(DynamicObject object) { - return System.identityHashCode(object); - } - - /** - * Delegate method for {@link DynamicObject#toString()}. - */ - @TruffleBoundary - public String toString(DynamicObject object) { - return "DynamicObject<" + this.toString() + ">@" + Integer.toHexString(hashCode(object)); - } - - /** - * Creates a data object to be associated with a newly created shape. - * - * @param shape the shape for which to create the data object - */ - public Object createShapeData(Shape shape) { - return null; - } - - public ForeignAccess getForeignAccessFactory() { - return ForeignAccess.create(new com.oracle.truffle.api.interop.ForeignAccess.Factory() { - - public boolean canHandle(TruffleObject obj) { - throw new IllegalArgumentException(this.toString() + " cannot be shared"); - } - - public CallTarget accessMessage(Message tree) { - throw new IllegalArgumentException(this.toString() + " cannot be shared; Message not possible: " + tree.toString()); - } - }); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Property.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Property.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2012, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -/** - * Property objects represent the mapping between property identifiers (keys) and storage locations. - * Optionally, properties may have metadata attached to them. - */ -public abstract class Property { - protected Property() { - } - - public static Property create(Object key, Location location, int flags) { - return Layout.getFactory().createProperty(key, location, flags); - } - - /** - * Get property identifier. - */ - public abstract Object getKey(); - - /** - * Get property flags. - */ - public abstract int getFlags(); - - /** - * Change the property's location. - * - * @return a Property with the new location (or {@code this} if the location is unchanged). - */ - public abstract Property relocate(Location newLocation); - - /** - * Gets the value of this property of the object. - * - * @param store the store that this property resides in - * @param shape the current shape of the object, which must contain this location - * @see DynamicObject#get(Object, Object) - */ - public abstract Object get(DynamicObject store, Shape shape); - - /** - * Gets the value of this property of the object. - * - * @param store the store that this property resides in - * @param condition the result of a shape check or {@code false} - * @see DynamicObject#get(Object, Object) - * @see #get(DynamicObject, Shape) - */ - public abstract Object get(DynamicObject store, boolean condition); - - /** - * Assigns value to this property of the object. - * - * Throws an exception if the value cannot be assigned to the property's current location. - * - * @param store the store that this property resides in - * @param value the value to assign - * @param shape the current shape of the object or {@code null} - * @throws IncompatibleLocationException if the value is incompatible with the property location - * @throws FinalLocationException if the location is final and values differ - * @see DynamicObject#set(Object, Object) - */ - public abstract void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException; - - /** - * Assigns value to this property of the object. - * - * Automatically relocates the property if the value cannot be assigned to its current location. - * - * @param shape the current shape of the object or {@code null} - */ - public abstract void setGeneric(DynamicObject store, Object value, Shape shape); - - /** - * Like {@link #set(DynamicObject, Object, Shape)}, but throws an {@link IllegalStateException} - * instead. - */ - public abstract void setSafe(DynamicObject store, Object value, Shape shape); - - /** - * Like {@link #setSafe}, but ignores the finalness of the property. For internal use only. - * - * @param store the store that this property resides in - * @param value the value to assign - */ - public abstract void setInternal(DynamicObject store, Object value); - - /** - * Assigns value to this property of the object, changing the object's shape. - * - * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and - * {@link #set(DynamicObject, Object, Shape)} to an atomic operation. - * - * @param store the store that this property resides in - * @param value the value to assign - * @param oldShape the shape before the transition - * @param newShape the shape after the transition - * @throws IncompatibleLocationException if the value is incompatible with the property location - */ - public abstract void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException; - - /** - * Assigns value to this property of the object, changing the object's shape. - * - * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and - * {@link #setGeneric(DynamicObject, Object, Shape)} to an atomic operation. - * - * @param store the store that this property resides in - * @param value the value to assign - * @param oldShape the shape before the transition - * @param newShape the shape after the transition - */ - public abstract void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape); - - /** - * Assigns value to this property of the object, changing the object's shape. - * - * Combines {@link DynamicObject#setShapeAndGrow(Shape, Shape)} and - * {@link #setSafe(DynamicObject, Object, Shape)} to an atomic operation. - * - * @param store the store that this property resides in - * @param value the value to assign - * @param oldShape the shape before the transition - * @param newShape the shape after the transition - */ - public abstract void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape); - - /** - * Returns {@code true} if this property and some other property have the same key and flags. - */ - public abstract boolean isSame(Property other); - - /** - * Get the property location. - */ - public abstract Location getLocation(); - - /** - * Is this property hidden from iteration. - * - * @see HiddenKey - */ - public abstract boolean isHidden(); - - public abstract boolean isShadow(); - - /** - * Create a copy of the property with the given flags. - */ - public abstract Property copyWithFlags(int newFlags); - - public abstract Property copyWithRelocatable(boolean newRelocatable); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Shape.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Shape.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2012, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -import java.util.*; - -import com.oracle.truffle.api.*; - -/** - * Shape objects create a mapping of Property objects to Locations. Shapes are immutable; adding or - * deleting a property yields a new Shape which links to the old one. This allows inline caching to - * simply check the identity of an object's Shape to determine if the cache is valid. There is one - * exception to this immutability, the transition map, but that is used simply to assure that an - * identical series of property additions and deletions will yield the same Shape object. - * - * @see DynamicObject - * @see Property - * @see Location - */ -public abstract class Shape { - /** - * Get a property entry by key. - * - * @param key the identifier to look up - * @return a Property object, or null if not found - */ - public abstract Property getProperty(Object key); - - /** - * Add a new property in the map, yielding a new or cached Shape object. - * - * @param property the property to add - * @return the new Shape - */ - public abstract Shape addProperty(Property property); - - /** - * An {@link Iterable} over the shape's properties in insertion order. - */ - public abstract Iterable getProperties(); - - /** - * Get a list of properties that this Shape stores. - * - * @return list of properties - */ - public abstract List getPropertyList(Pred filter); - - /** - * Get a list of all properties that this Shape stores. - * - * @return list of properties - */ - public abstract List getPropertyList(); - - /** - * Returns all (also hidden) property objects in this shape. - * - * @param ascending desired order ({@code true} for insertion order, {@code false} for reverse - * insertion order) - */ - public abstract List getPropertyListInternal(boolean ascending); - - /** - * Get a filtered list of property keys in insertion order. - */ - public abstract List getKeyList(Pred filter); - - /** - * Get a list of all property keys in insertion order. - */ - public abstract List getKeyList(); - - /** - * Get all property keys in insertion order. - */ - public abstract Iterable getKeys(); - - /** - * Get an assumption that the shape is valid. - */ - public abstract Assumption getValidAssumption(); - - /** - * Check whether this shape is valid. - */ - public abstract boolean isValid(); - - /** - * Get an assumption that the shape is a leaf. - */ - public abstract Assumption getLeafAssumption(); - - /** - * Check whether this shape is a leaf in the transition graph, i.e. transitionless. - */ - public abstract boolean isLeaf(); - - /** - * @return the parent shape or {@code null} if none. - */ - public abstract Shape getParent(); - - /** - * Check whether the shape has a property with the given key. - */ - public abstract boolean hasProperty(Object key); - - /** - * Remove the given property from the shape. - */ - public abstract Shape removeProperty(Property property); - - /** - * Replace a property in the shape. - */ - public abstract Shape replaceProperty(Property oldProperty, Property newProperty); - - /** - * Get the last added property. - */ - public abstract Property getLastProperty(); - - public abstract int getId(); - - /** - * Append the property, relocating it to the next allocated location. - */ - public abstract Shape append(Property oldProperty); - - /** - * Obtain an {@link Allocator} instance for the purpose of allocating locations. - */ - public abstract Allocator allocator(); - - /** - * Get number of properties in this shape. - */ - public abstract int getPropertyCount(); - - /** - * Get the shape's operations. - */ - public abstract ObjectType getObjectType(); - - /** - * Get the root shape. - */ - public abstract Shape getRoot(); - - /** - * Check whether this shape is identical to the given shape. - */ - public abstract boolean check(DynamicObject subject); - - /** - * Get the shape's layout. - */ - public abstract Layout getLayout(); - - /** - * Get the shape's custom data. - */ - public abstract Object getData(); - - /** - * Get the shape's shared data. - */ - public abstract Object getSharedData(); - - /** - * Query whether the shape has a transition with the given key. - */ - public abstract boolean hasTransitionWithKey(Object key); - - /** - * Clone off a separate shape with new shared data. - */ - public abstract Shape createSeparateShape(Object sharedData); - - /** - * Change the shape's type, yielding a new shape. - */ - public abstract Shape changeType(ObjectType newOps); - - /** - * Reserve the primitive extension array field. - */ - public abstract Shape reservePrimitiveExtensionArray(); - - /** - * Create a new {@link DynamicObject} instance with this shape. - */ - public abstract DynamicObject newInstance(); - - /** - * Create a {@link DynamicObjectFactory} for creating instances of this shape. - */ - public abstract DynamicObjectFactory createFactory(); - - /** - * Get mutex object shared by related shapes, i.e. shapes with a common root. - */ - public abstract Object getMutex(); - - public abstract int getObjectArraySize(); - - public abstract int getObjectFieldSize(); - - public abstract int getPrimitiveArraySize(); - - public abstract int getPrimitiveFieldSize(); - - public abstract int getObjectArrayCapacity(); - - public abstract int getPrimitiveArrayCapacity(); - - public abstract boolean hasPrimitiveArray(); - - /** - * Are these two shapes related, i.e. do they have the same root? - * - * @param other Shape to compare to - * @return true if one shape is an upcast of the other, or the Shapes are equal - */ - public abstract boolean isRelated(Shape other); - - public abstract Shape tryMerge(Shape other); - - public R accept(ShapeVisitor visitor) { - return visitor.visitShape(this); - } - - public abstract static class Allocator { - protected abstract Location locationForValue(Object value, boolean useFinal, boolean nonNull); - - public final Location locationForValue(Object value) { - return locationForValue(value, false, value != null); - } - - public final Location locationForValue(Object value, EnumSet modifiers) { - assert value != null || !modifiers.contains(LocationModifier.NonNull); - return locationForValue(value, modifiers.contains(LocationModifier.Final), modifiers.contains(LocationModifier.NonNull)); - } - - protected abstract Location locationForType(Class type, boolean useFinal, boolean nonNull); - - public final Location locationForType(Class type) { - return locationForType(type, false, false); - } - - public final Location locationForType(Class type, EnumSet modifiers) { - return locationForType(type, modifiers.contains(LocationModifier.Final), modifiers.contains(LocationModifier.NonNull)); - } - - public abstract Location constantLocation(Object value); - - public abstract Location declaredLocation(Object value); - - public abstract Allocator addLocation(Location location); - } - - /** - * Represents a predicate (boolean-valued function) of one argument. For Java 7 compatibility. - * - * @param the type of the input to the predicate - */ - public interface Pred { - /** - * Evaluates this predicate on the given argument. - * - * @param t the input argument - * @return {@code true} if the input argument matches the predicate, otherwise {@code false} - */ - boolean test(T t); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ShapeListener.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ShapeListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface ShapeListener { - /** - * Called when a property is added, removed, or replaced. - * - * @param key identifier of the property - */ - void onPropertyTransition(Object key); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ShapeVisitor.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/ShapeVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface ShapeVisitor { - R visitShape(Shape shape); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/TypedLocation.java --- a/graal/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/TypedLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.object; - -public interface TypedLocation extends BaseLocation { - /** - * The type of this location. - */ - Class getType(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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(null); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return value; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +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 java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.Node.Child; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +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 java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @Test - public void test() { - 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(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); - } - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +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 java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Test child fields declared with interface types instead of {@link Node} subclasses. - */ -public class InterfaceChildFieldTest { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +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.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - *

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 { - - @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(null); - } - - @Override - public Object execute(VirtualFrame frame) { - return 42; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +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 static org.junit.Assert.*; - -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * 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(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +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.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - *

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 setUp() { - this.runtime = Truffle.getRuntime(); - } - - private static RootNode createTestRootNode() { - return new RootNode() { - @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(); - RootCallTarget target = runtime.createCallTarget(rootNode); - assertNotNull(target); - assertEquals(target.call(), 42); - assertSame(rootNode, target.getRootNode()); - } - - @Test - public void testGetCallTargets1() { - RootNode rootNode = createTestRootNode(); - RootCallTarget target = runtime.createCallTarget(rootNode); - assertTrue(runtime.getCallTargets().contains(target)); - } - - @Test - public void testGetCallTargets2() { - RootNode rootNode = createTestRootNode(); - 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(); - rootNode1.assignSourceSection(sourceSection1); - RootNode rootNode2 = createTestRootNode(); - rootNode2.assignSourceSection(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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +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.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestAdditionNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestAdvancedInstrumentCounterRoot; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestRootNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestValueNode; - -/** - * Tests the kind of instrumentation where a client can provide an AST fragment to be - * spliced directly into the AST. - */ -public class AdvancedInstrumentTest { - - @Test - public void testAdvancedInstrumentListener() { - // Create a simple addition AST - final TruffleRuntime runtime = Truffle.getRuntime(); - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - final TestRootNode rootNode = new TestRootNode(addNode); - final CallTarget callTarget1 = runtime.createCallTarget(rootNode); - - // Ensure it executes correctly - assertEquals(13, callTarget1.call()); - - // Probe the addition node - final Probe probe = addNode.probe(); - - assertEquals(13, callTarget1.call()); - - // Attach a null factory; it never actually attaches a node. - final Instrument instrument = Instrument.create(null, new AdvancedInstrumentRootFactory() { - - public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { - return null; - } - }, null, "test AdvancedInstrument"); - probe.attach(instrument); - - assertEquals(13, callTarget1.call()); - - final TestAdvancedInstrumentCounterRoot counter = new TestAdvancedInstrumentCounterRoot(); - - // Attach a factory that splices an execution counter into the AST. - probe.attach(Instrument.create(null, new AdvancedInstrumentRootFactory() { - - public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { - return counter; - } - }, null, "test AdvancedInstrument")); - assertEquals(0, counter.getCount()); - - assertEquals(13, callTarget1.call()); - - assertEquals(1, counter.getCount()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,550 +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.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeFailure.Reason; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.nodes.*; -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.TestRootNode; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestValueNode; - -/** - *

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 Instrument} that might be attached to the particular probe by tools. - *
    - *
  1. Creates a simple add AST
  2. - *
  3. Verifies its structure
  4. - *
  5. "Probes" the add node by adding a {@link WrapperNode} and associated {@link Probe}
  6. - *
  7. Attaches a simple {@link Instrument} to the node via the Probe's {@link ProbeNode}
  8. - *
  9. Verifies the structure of the probed AST
  10. - *
  11. Verifies the execution of the probed AST
  12. - *
  13. Verifies the results observed by the instrument.
  14. - *
- * To do these tests, several required classes have been implemented in their most basic form, only - * implementing the methods necessary for the tests to pass, with stubs elsewhere. - */ -public class InstrumentationTest { - - private static final SyntaxTag ADD_TAG = new SyntaxTag() { - - @Override - public String name() { - return "Addition"; - } - - @Override - public String getDescription() { - return "Test Language Addition Node"; - } - }; - - private static final SyntaxTag VALUE_TAG = new SyntaxTag() { - - @Override - public String name() { - return "Value"; - } - - @Override - public String getDescription() { - return "Test Language Value Node"; - } - }; - - @Test - public void testInstrumentationStructure() { - // Create a simple addition AST - final TruffleRuntime runtime = Truffle.getRuntime(); - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - - try { - addNode.probe(); - } catch (ProbeException e) { - assertEquals(e.getFailure().getReason(), Reason.NO_PARENT); - } - final TestRootNode rootNode = new TestRootNode(addNode); - - // Creating a call target sets the parent pointers in this tree and is necessary prior to - // checking any parent/child relationships - final CallTarget callTarget1 = runtime.createCallTarget(rootNode); - - // Check the tree structure - assertEquals(addNode, leftValueNode.getParent()); - assertEquals(addNode, rightValueNode.getParent()); - Iterator iterator = addNode.getChildren().iterator(); - assertEquals(leftValueNode, iterator.next()); - assertEquals(rightValueNode, iterator.next()); - assertFalse(iterator.hasNext()); - assertEquals(rootNode, addNode.getParent()); - iterator = rootNode.getChildren().iterator(); - assertEquals(addNode, iterator.next()); - assertFalse(iterator.hasNext()); - - // Ensure it executes correctly - assertEquals(13, callTarget1.call()); - - // Probe the addition node - addNode.probe(); - - // Check the modified tree structure - assertEquals(addNode, leftValueNode.getParent()); - assertEquals(addNode, rightValueNode.getParent()); - iterator = addNode.getChildren().iterator(); - assertEquals(leftValueNode, iterator.next()); - assertEquals(rightValueNode, iterator.next()); - assertFalse(iterator.hasNext()); - - // Ensure there's a WrapperNode correctly inserted into the AST - iterator = rootNode.getChildren().iterator(); - Node wrapperNode = iterator.next(); - assertTrue(wrapperNode instanceof TestLanguageWrapperNode); - assertFalse(iterator.hasNext()); - assertEquals(rootNode, wrapperNode.getParent()); - - // Check that the WrapperNode has both the probe and the wrapped node as children - iterator = wrapperNode.getChildren().iterator(); - assertEquals(addNode, iterator.next()); - ProbeNode probeNode = (ProbeNode) iterator.next(); - assertTrue(probeNode.getProbe() != null); - assertFalse(iterator.hasNext()); - - // Check that you can't probe the WrapperNodes - TestLanguageWrapperNode wrapper = (TestLanguageWrapperNode) wrapperNode; - try { - wrapper.probe(); - fail(); - } catch (ProbeException e) { - assertEquals(e.getFailure().getReason(), Reason.WRAPPER_NODE); - } - - // Check that the "probed" AST still executes correctly - assertEquals(13, callTarget1.call()); - } - - @Test - public void testListeners() { - - // Create a simple addition AST - final TruffleRuntime runtime = Truffle.getRuntime(); - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - final TestRootNode rootNode = new TestRootNode(addNode); - - // Creating a call target sets the parent pointers in this tree and is necessary prior to - // checking any parent/child relationships - final CallTarget callTarget = runtime.createCallTarget(rootNode); - // Probe the addition node - final Probe probe = addNode.probe(); - - // Check instrumentation with the simplest kind of counters. - // They should all be removed when the check is finished. - checkCounters(probe, callTarget, rootNode, new TestSimpleInstrumentCounter(), new TestSimpleInstrumentCounter(), new TestSimpleInstrumentCounter()); - - // Now try with the more complex flavor of listener - checkCounters(probe, callTarget, rootNode, new TestStandardInstrumentCounter(), new TestStandardInstrumentCounter(), new TestStandardInstrumentCounter()); - } - - private static void checkCounters(Probe probe, CallTarget callTarget, RootNode rootNode, TestCounter counterA, TestCounter counterB, TestCounter counterC) { - - // 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, callTarget.call()); - 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, callTarget.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 2); - assertEquals(counterB.leaveCount(), 2); - - // Simulate a split by cloning the AST - final CallTarget callTarget2 = Truffle.getRuntime().createCallTarget((TestRootNode) rootNode.copy()); - // Run the clone and check that instrument B is still working but not A - assertEquals(13, callTarget2.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 3); - assertEquals(counterB.leaveCount(), 3); - - // Run the original and check that instrument B is still working but not A - assertEquals(13, callTarget2.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 4); - assertEquals(counterB.leaveCount(), 4); - - // 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, callTarget.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 5); - assertEquals(counterB.leaveCount(), 5); - assertEquals(counterC.enterCount(), 1); - assertEquals(counterC.leaveCount(), 1); - - // Run the clone and check that instruments B,C working but not A - assertEquals(13, callTarget2.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 6); - assertEquals(counterB.leaveCount(), 6); - assertEquals(counterC.enterCount(), 2); - assertEquals(counterC.leaveCount(), 2); - - // Remove instrumentC - counterC.dispose(); - - // Run the original and check that instrument B working but not A,C - assertEquals(13, callTarget.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 7); - assertEquals(counterB.leaveCount(), 7); - assertEquals(counterC.enterCount(), 2); - assertEquals(counterC.leaveCount(), 2); - - // Run the clone and check that instrument B working but not A,C - assertEquals(13, callTarget2.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 8); - assertEquals(counterB.leaveCount(), 8); - assertEquals(counterC.enterCount(), 2); - assertEquals(counterC.leaveCount(), 2); - - // Remove instrumentB - counterB.dispose(); - - // Run both the original and clone, check that no instruments working - assertEquals(13, callTarget.call()); - assertEquals(13, callTarget2.call()); - assertEquals(counterA.enterCount(), 1); - assertEquals(counterA.leaveCount(), 1); - assertEquals(counterB.enterCount(), 8); - assertEquals(counterB.leaveCount(), 8); - assertEquals(counterC.enterCount(), 2); - assertEquals(counterC.leaveCount(), 2); - } - - @Test - public void testTagging() { - // Applies appropriate tags - final TestASTProber astProber = new TestASTProber(); - Probe.registerASTProber(astProber); - - // Listens for probes and tags being added - final TestProbeListener probeListener = new TestProbeListener(); - Probe.addProbeListener(probeListener); - - // Counts all entries to all instances of addition nodes - final TestMultiCounter additionCounter = new TestMultiCounter(); - - // Counts all entries to all instances of value nodes - final TestMultiCounter valueCounter = new TestMultiCounter(); - - // Create a simple addition AST - final TruffleRuntime runtime = Truffle.getRuntime(); - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - - final TestRootNode rootNode = new TestRootNode(addNode); - - final CallTarget callTarget = runtime.createCallTarget(rootNode); - - // Check that the prober added probes to the tree - assertEquals(probeListener.probeCount, 3); - assertEquals(probeListener.tagCount, 3); - - assertEquals(Probe.findProbesTaggedAs(ADD_TAG).size(), 1); - assertEquals(Probe.findProbesTaggedAs(VALUE_TAG).size(), 2); - - // Check that it executes correctly - assertEquals(13, callTarget.call()); - - // Dynamically attach a counter for all executions of all Addition nodes - for (Probe probe : Probe.findProbesTaggedAs(ADD_TAG)) { - additionCounter.attachCounter(probe); - } - // Dynamically attach a counter for all executions of all Value nodes - for (Probe probe : Probe.findProbesTaggedAs(VALUE_TAG)) { - valueCounter.attachCounter(probe); - } - - // Counters initialized at 0 - assertEquals(additionCounter.count, 0); - assertEquals(valueCounter.count, 0); - - // Execute again - assertEquals(13, callTarget.call()); - - // There are two value nodes in the AST, but only one addition node - assertEquals(additionCounter.count, 1); - assertEquals(valueCounter.count, 2); - - Probe.unregisterASTProber(astProber); - } - - 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 final Instrument instrument; - - public TestSimpleInstrumentCounter() { - this.instrument = Instrument.create(new SimpleInstrumentListener() { - - public void enter(Probe probe) { - enterCount++; - } - - public void returnVoid(Probe probe) { - leaveCount++; - } - - public void returnValue(Probe probe, Object result) { - leaveCount++; - } - - public void returnExceptional(Probe probe, Exception exception) { - leaveCount++; - } - - }, "Instrumentation Test Counter"); - } - - @Override - public int enterCount() { - return enterCount; - } - - @Override - public int leaveCount() { - return leaveCount; - } - - @Override - public void attach(Probe probe) { - probe.attach(instrument); - } - - @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 Instrument instrument; - - public TestStandardInstrumentCounter() { - this.instrument = Instrument.create(new StandardInstrumentListener() { - - public void enter(Probe probe, Node node, VirtualFrame vFrame) { - enterCount++; - } - - public void returnVoid(Probe probe, Node node, VirtualFrame vFrame) { - leaveCount++; - } - - public void returnValue(Probe probe, Node node, VirtualFrame vFrame, Object result) { - leaveCount++; - } - - public void returnExceptional(Probe probe, Node node, VirtualFrame vFrame, Exception exception) { - leaveCount++; - } - - }, "Instrumentation Test Counter"); - } - - @Override - public int enterCount() { - return enterCount; - } - - @Override - public int leaveCount() { - return leaveCount; - } - - @Override - public void attach(Probe probe) { - probe.attach(instrument); - } - - @Override - public void dispose() { - instrument.dispose(); - } - } - - /** - * Tags selected nodes on newly constructed ASTs. - */ - private static final class TestASTProber implements NodeVisitor, ASTProber { - - @Override - public boolean visit(Node node) { - if (node instanceof TestLanguageNode) { - - final TestLanguageNode testNode = (TestLanguageNode) node; - - if (node instanceof TestValueNode) { - testNode.probe().tagAs(VALUE_TAG, null); - - } else if (node instanceof TestAdditionNode) { - testNode.probe().tagAs(ADD_TAG, null); - - } - } - return true; - } - - @Override - public void probeAST(Node node) { - node.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 enter(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 enter(Probe probe, Node node, VirtualFrame vFrame) { - counter++; - } - } - - /** - * A counter that can count executions at multiple nodes; it attaches a separate instrument at - * each Probe, but keeps a total count. - */ - private static final class TestMultiCounter { - - public int count = 0; - - public void attachCounter(Probe probe) { - - // Attach a new instrument for every Probe - // where we want to count executions. - // it will get copied when ASTs cloned, so - // keep the count in this outer class. - probe.attach(Instrument.create(new DefaultSimpleInstrumentListener() { - - @Override - public void enter(Probe p) { - count++; - } - }, "Instrumentation Test MultiCounter")); - } - } - - 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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +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.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; - -/** - * 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); - - @Override - public boolean isInstrumentable() { - return true; - } - - @Override - public WrapperNode createWrapperNode() { - return new TestLanguageWrapperNode(this); - } - } - - @NodeInfo(cost = NodeCost.NONE) - static class TestLanguageWrapperNode extends TestLanguageNode implements WrapperNode { - @Child private TestLanguageNode child; - @Child private ProbeNode probeNode; - - public TestLanguageWrapperNode(TestLanguageNode child) { - assert !(child instanceof TestLanguageWrapperNode); - this.child = child; - } - - @Override - public String instrumentationInfo() { - return "Wrapper node for testing"; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public void insertProbe(ProbeNode newProbeNode) { - this.probeNode = newProbeNode; - } - - @Override - public Probe getProbe() { - return probeNode.getProbe(); - } - - @Override - public Node getChild() { - return child; - } - - @Override - public Object execute(VirtualFrame vFrame) { - probeNode.enter(child, vFrame); - Object result; - try { - result = child.execute(vFrame); - probeNode.returnValue(child, vFrame, result); - } catch (KillException e) { - throw (e); - } catch (Exception e) { - probeNode.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 TestRootNode 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 TestRootNode(TestLanguageNode body) { - super(null); - this.body = body; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return body.execute(vFrame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - - @Override - public void applyInstrumentation() { - Probe.applyASTProbers(body); - } - } - - static class TestAdvancedInstrumentCounterRoot extends AdvancedInstrumentRoot { - - private long count; - - @Override - public Object executeRoot(Node node, VirtualFrame vFrame) { - count++; - return null; - } - - public long getCount() { - return count; - } - - public String instrumentationInfo() { - return null; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/NodeUtilTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/NodeUtilTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -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; - - @Override - public Object execute(VirtualFrame frame) { - return null; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/SafeReplaceTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/SafeReplaceTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * 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; - - @Override - public Object execute(VirtualFrame frame) { - executed++; - child.execute(); - return null; - } - } - - private static class WrongTestNode extends Node { - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/PostOrderDeserializerTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/PostOrderDeserializerTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +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.serial; - -import java.nio.*; -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.serial.*; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.EmptyNode; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithArray; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithFields; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithOneChild; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithThreeChilds; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithTwoArray; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithTwoChilds; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.StringNode; - -public class PostOrderDeserializerTest { - - private PostOrderDeserializer d; - private TestSerializerConstantPool cp; - - @Before - public void setUp() { - cp = new TestSerializerConstantPool(); - d = new PostOrderDeserializer(cp); - } - - @After - public void tearDown() { - d = null; - cp = null; - } - - private Node deserialize(byte[] bytes) { - return d.deserialize(bytes, Node.class); - } - - @Test - public void testNull() { - createCP(); - Node ast = deserialize(createBytes(VariableLengthIntBuffer.NULL)); - Assert.assertNull(ast); - } - - @Test - public void testSingleNode() { - createCP(EmptyNode.class); - Node expectedAst = new EmptyNode(); - Node ast = deserialize(createBytes(0)); - assertAST(expectedAst, ast); - } - - @Test - public void testThreeChilds() { - createCP(EmptyNode.class, NodeWithThreeChilds.class); - Node expectedAst = new NodeWithThreeChilds(new EmptyNode(), null, new EmptyNode()); - Node ast = deserialize(createBytes(0, VariableLengthIntBuffer.NULL, 0, 1)); - assertAST(expectedAst, ast); - } - - @Test - public void testFields() { - createCP(NodeWithFields.class, "test", Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE, Float.MIN_VALUE, Float.MAX_VALUE, Double.MIN_VALUE, Double.MAX_VALUE, - (int) Character.MIN_VALUE, (int) Character.MAX_VALUE, (int) Short.MIN_VALUE, (int) Short.MAX_VALUE, (int) Byte.MIN_VALUE, (int) Byte.MAX_VALUE, 1); - NodeWithFields expectedAst = new NodeWithFields("test", Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE, Float.MIN_VALUE, Float.MAX_VALUE, Double.MIN_VALUE, - Double.MAX_VALUE, Character.MIN_VALUE, Character.MAX_VALUE, Short.MIN_VALUE, Short.MAX_VALUE, Byte.MIN_VALUE, Byte.MAX_VALUE, Boolean.TRUE, Boolean.FALSE); - Node ast = deserialize(createBytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 10)); - assertAST(expectedAst, ast); - } - - @Test - public void testFieldsNull() { - createCP(NodeWithFields.class, "test", 0, 0L, 0.0F, 0.0D); - NodeWithFields expectedAst = new NodeWithFields("test", 0, null, 0L, null, 0f, null, 0d, null, (char) 0, null, (short) 0, null, (byte) 0, null, false, null); - int nil = VariableLengthIntBuffer.NULL; - Node ast = deserialize(createBytes(0, 1, 2, nil, 3, nil, 4, nil, 5, nil, 2, nil, 2, nil, 2, nil, 2, nil)); - assertAST(expectedAst, ast); - } - - @Test - public void testNullChilds() { - createCP(Node[].class, NodeWithArray.class); - Node expectedAst = new NodeWithArray(null); - Node ast = deserialize(createBytes(0, VariableLengthIntBuffer.NULL, 1)); - assertAST(expectedAst, ast); - } - - @Test - public void testNChilds() { - Node expectedAst = new NodeWithArray(new Node[]{new EmptyNode(), new NodeWithArray(new Node[]{new EmptyNode(), new EmptyNode(), new EmptyNode()}), new EmptyNode(), new EmptyNode()}); - createCP(Node[].class, 4, EmptyNode.class, 3, NodeWithArray.class); - Node ast = deserialize(createBytes(0, 1, 2, 0, 3, 2, 2, 2, 4, 2, 2, 4)); - - assertAST(expectedAst, ast); - } - - @Test - public void test2xNChilds() { - Node expectedAst = new NodeWithTwoArray(new Node[]{new StringNode("a0"), new StringNode("a1")}, new Node[]{new StringNode("b0"), new StringNode("b1"), new StringNode("b2")}); - createCP(Node[].class, 2, StringNode.class, "a0", "a1", 3, "b0", "b1", "b2", NodeWithTwoArray.class); - Node ast = deserialize(createBytes(0, 1, 2, 3, 2, 4, 0, 5, 2, 6, 2, 7, 2, 8, 9)); - - assertAST(expectedAst, ast); - } - - @Test - public void testBug0() { - Node expectedAst = new NodeWithArray(new Node[]{new NodeWithOneChild(new EmptyNode())}); - - createCP(Node[].class, 1, EmptyNode.class, NodeWithOneChild.class, NodeWithArray.class); - Node ast = deserialize(createBytes(0, 1, 2, 3, 4)); - assertAST(expectedAst, ast); - } - - @Test - public void testBug1() { - Node expectedAst = new NodeWithArray(new Node[]{new NodeWithTwoChilds(new EmptyNode(), new EmptyNode())}); - - createCP(Node[].class, 1, EmptyNode.class, NodeWithTwoChilds.class, NodeWithArray.class); - Node ast = deserialize(createBytes(0, 1, 2, 2, 3, 4)); - assertAST(expectedAst, ast); - } - - private static void assertAST(Node expectedAst, Node actualAst) { - if (expectedAst == null) { - Assert.assertNull(actualAst); - return; - } - - expectedAst.adoptChildren(); - - Assert.assertNotNull(actualAst); - // fields are asserted using the corresponding equals implementation - Assert.assertEquals(expectedAst, actualAst); - - Iterable expectedChildIterator = expectedAst.getChildren(); - Iterator actualChildIterator = actualAst.getChildren().iterator(); - for (Node node : expectedChildIterator) { - Assert.assertTrue(actualChildIterator.hasNext()); - assertAST(node, actualChildIterator.next()); - } - Assert.assertFalse(actualChildIterator.hasNext()); - } - - private static byte[] createBytes(int... refs) { - VariableLengthIntBuffer buf = new VariableLengthIntBuffer(ByteBuffer.allocate(512)); - for (int i = 0; i < refs.length; i++) { - buf.put(refs[i]); - } - return buf.getBytes(); - } - - private void createCP(Object... cpData) { - for (int i = 0; i < cpData.length; i++) { - Object object = cpData[i]; - - cp.putObject(object.getClass(), object); - - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/PostOrderSerializerTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/PostOrderSerializerTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +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.serial; - -import org.junit.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.serial.*; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.EmptyNode; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithArray; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithFields; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithThreeChilds; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.NodeWithTwoArray; -import com.oracle.truffle.api.test.nodes.serial.TestNodes.StringNode; - -public class PostOrderSerializerTest { - - private PostOrderSerializer s; - private TestSerializerConstantPool cp; - - @Before - public void setUp() { - cp = new TestSerializerConstantPool(); - s = new PostOrderSerializer(cp); - } - - @After - public void tearDown() { - cp = null; - s = null; - } - - @Test - public void testNull() { - Node ast = null; - assertBytes(s.serialize(ast), VariableLengthIntBuffer.NULL); - assertCP(); - } - - @Test - public void testSingleEmptyNode() { - Node ast = new EmptyNode(); - assertBytes(s.serialize(ast), 0); - assertCP(EmptyNode.class); - } - - @Test - public void testThreeChilds() { - Node ast = new NodeWithThreeChilds(new EmptyNode(), null, new EmptyNode()); - assertBytes(s.serialize(ast), 0, VariableLengthIntBuffer.NULL, 0, 1); - assertCP(EmptyNode.class, NodeWithThreeChilds.class); - } - - @Test - public void testFields() { - NodeWithFields ast = new NodeWithFields("test", Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE, Float.MIN_VALUE, Float.MAX_VALUE, Double.MIN_VALUE, Double.MAX_VALUE, - Character.MIN_VALUE, Character.MAX_VALUE, Short.MIN_VALUE, Short.MAX_VALUE, Byte.MIN_VALUE, Byte.MAX_VALUE, Boolean.TRUE, Boolean.FALSE); - assertBytes(s.serialize(ast), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 10); - assertCP(NodeWithFields.class, "test", Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE, Float.MIN_VALUE, Float.MAX_VALUE, Double.MIN_VALUE, Double.MAX_VALUE, - (int) Character.MIN_VALUE, (int) Character.MAX_VALUE, (int) Short.MIN_VALUE, (int) Short.MAX_VALUE, (int) Byte.MIN_VALUE, (int) Byte.MAX_VALUE, 1); - } - - @Test - public void testFieldsNull() { - NodeWithFields ast = new NodeWithFields("test", 0, null, 0L, null, 0f, null, 0d, null, (char) 0, null, (short) 0, null, (byte) 0, null, false, null); - int nil = VariableLengthIntBuffer.NULL; - assertBytes(s.serialize(ast), 0, 1, 2, nil, 3, nil, 4, nil, 5, nil, 2, nil, 2, nil, 2, nil, 2, nil); - assertCP(NodeWithFields.class, "test", 0, 0L, 0.0F, 0.0D); - } - - @Test - public void testNChilds() { - Node ast = new NodeWithArray(new Node[]{new EmptyNode(), new NodeWithArray(new Node[]{new EmptyNode(), new EmptyNode(), new EmptyNode()}), new EmptyNode(), new EmptyNode()}); - assertBytes(s.serialize(ast), 0, 1, 2, 0, 3, 2, 2, 2, 4, 2, 2, 4); - assertCP(Node[].class, 4, EmptyNode.class, 3, NodeWithArray.class); - } - - @Test - public void testNullChilds() { - Node ast = new NodeWithArray(null); - assertBytes(s.serialize(ast), 0, VariableLengthIntBuffer.NULL, 1); - assertCP(Node[].class, NodeWithArray.class); - } - - @Test - public void test2xNChilds() { - Node ast = new NodeWithTwoArray(new Node[]{new StringNode("a0"), new StringNode("a1")}, new Node[]{new StringNode("b0"), new StringNode("b1"), new StringNode("b2")}); - assertBytes(s.serialize(ast), 0, 1, 2, 3, 2, 4, 0, 5, 2, 6, 2, 7, 2, 8, 9); - assertCP(Node[].class, 2, StringNode.class, "a0", "a1", 3, "b0", "b1", "b2", NodeWithTwoArray.class); - } - - private static void assertBytes(byte[] actualBytes, int... expectedIndexes) { - VariableLengthIntBuffer buf = new VariableLengthIntBuffer(actualBytes); - for (int i = 0; i < expectedIndexes.length; i++) { - Assert.assertTrue("Unexpected EOF " + i, buf.hasRemaining()); - Assert.assertEquals("Index at pos " + i + ".", expectedIndexes[i], buf.get()); - } - Assert.assertFalse(buf.hasRemaining()); - } - - private void assertCP(Object... object) { - for (int i = 0; i < object.length; i++) { - Object cpvalue = object[i]; - Assert.assertNotNull("CP at index " + i, cpvalue); - Assert.assertEquals("CP at index " + i, cpvalue, cp.getObject(cpvalue.getClass(), i)); - } - Assert.assertEquals(object.length, cp.getIndex()); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/TestNodes.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/TestNodes.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +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.serial; - -import java.util.*; - -import com.oracle.truffle.api.nodes.*; - -final class TestNodes { - - private TestNodes() { - } - - static class StringNode extends Node { - - private final String name; - - public StringNode(String name) { - this.name = name; - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } else if (obj.getClass() != getClass()) { - return false; - } else if ((((Node) obj).getParent() != null) && !((Node) obj).getParent().equals(getParent())) { - return false; - } else if (!Objects.equals(name, ((StringNode) obj).name)) { - return false; - } - return true; - } - } - - static class EmptyNode extends Node { - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } else if (obj.getClass() != getClass()) { - return false; - } else if ((((Node) obj).getParent() != null) && !((Node) obj).getParent().equals(getParent())) { - return false; - } - return true; - } - } - - static class NodeWithOneChild extends EmptyNode { - - @Child Node child; - - public NodeWithOneChild(Node child) { - this.child = child; - } - - } - - static class NodeWithTwoChilds extends EmptyNode { - - @Child Node child1; - @Child Node child2; - - public NodeWithTwoChilds(Node child1, Node child2) { - this.child1 = child1; - this.child2 = child2; - } - - } - - static class NodeWithThreeChilds extends EmptyNode { - - @Child Node child1; - @Child Node child2; - @Child Node child3; - - public NodeWithThreeChilds(Node child1, Node child2, Node child3) { - this.child1 = child1; - this.child2 = child2; - this.child3 = child3; - } - - } - - static class NodeWithArray extends EmptyNode { - - @Children private final Node[] childNodes; - - NodeWithArray(Node[] children) { - this.childNodes = children; - } - - Node[] getChildNodes() { - return childNodes; - } - } - - static class NodeWithTwoArray extends EmptyNode { - - @Children private final Node[] childNodes1; - @Children private final Node[] childNodes2; - - NodeWithTwoArray(Node[] childs1, Node[] childs2) { - this.childNodes1 = childs1; - this.childNodes2 = childs2; - } - - Node[] getChildNodes1() { - return childNodes1; - } - - Node[] getChildNodes2() { - return childNodes2; - } - } - - static class NodeWithFields extends EmptyNode { - - String stringField; - int integerField; - Integer integerObjectField; - long longField; - Long longObjectField; - float floatField; - Float floatObjectField; - double doubleField; - Double doubleObjectField; - char charField; - Character charObjectField; - short shortField; - Short shortObjecField; - byte byteField; - Byte byteObjectField; - boolean booleanField; - Boolean booleanObjectfield; - - public NodeWithFields(String stringField, int integerField, Integer integerObjectField, long longField, Long longObjectField, float floatField, Float floatObjectField, double doubleField, - Double doubleObjectField, char charField, Character charObjectField, short shortField, Short shortObjecField, byte byteField, Byte byteObjectField, boolean booleanField, - Boolean booleanObjectfield) { - this.stringField = stringField; - this.integerField = integerField; - this.integerObjectField = integerObjectField; - this.longField = longField; - this.longObjectField = longObjectField; - this.floatField = floatField; - this.floatObjectField = floatObjectField; - this.doubleField = doubleField; - this.doubleObjectField = doubleObjectField; - this.charField = charField; - this.charObjectField = charObjectField; - this.shortField = shortField; - this.shortObjecField = shortObjecField; - this.byteField = byteField; - this.byteObjectField = byteObjectField; - this.booleanField = booleanField; - this.booleanObjectfield = booleanObjectfield; - } - - @Override - public int hashCode() { - return Objects.hash(stringField, integerField, integerObjectField, longField, longObjectField, floatField, floatObjectField, doubleField, doubleObjectField, charField, charObjectField, - shortField, shortObjecField, byteField, byteObjectField, booleanField, booleanObjectfield); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj.getClass() != getClass()) { - return false; - } - NodeWithFields o = (NodeWithFields) obj; - return Objects.deepEquals(fieldArray(), o.fieldArray()); - } - - private Object[] fieldArray() { - return array(stringField, integerField, integerObjectField, longField, longObjectField, floatField, floatObjectField, doubleField, doubleObjectField, charField, charObjectField, - shortField, shortObjecField, byteField, byteObjectField, booleanField, booleanObjectfield); - } - - private static Object[] array(Object... values) { - return values; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/TestSerializerConstantPool.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/TestSerializerConstantPool.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +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.serial; - -import java.util.*; - -import com.oracle.truffle.api.nodes.serial.*; - -class TestSerializerConstantPool implements SerializerConstantPool { - - private final Map int2object = new HashMap<>(); - private final Map object2int = new HashMap<>(); - - private int index; - - public void setIndex(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - @Override - public double getDouble(int cpi) { - return (Double) int2object.get(cpi); - } - - @Override - public float getFloat(int cpi) { - return (Float) int2object.get(cpi); - } - - @Override - public Object getObject(Class clazz, int cpi) throws UnsupportedConstantPoolTypeException { - return int2object.get(cpi); - } - - @Override - public int putDouble(double value) { - return put(value); - } - - public int putFloat(float value) { - return put(value); - } - - public int putObject(java.lang.Class clazz, Object value) throws UnsupportedConstantPoolTypeException { - return put(value); - } - - @Override - public int putClass(Class clazz) { - return put(clazz); - } - - private int put(Object o) { - Integer currentIndex = object2int.get(o); - if (currentIndex == null) { - int2object.put(index, o); - object2int.put(o, index); - return index++; - } else { - return currentIndex; - } - } - - @Override - public Class getClass(int idx) { - return (Class) int2object.get(idx); - } - - @Override - public int putInt(int constant) { - return put(constant); - } - - @Override - public int getInt(int idx) { - return (Integer) int2object.get(idx); - } - - @Override - public long getLong(int idx) { - return (Long) int2object.get(idx); - } - - @Override - public int putLong(long value) { - return put(value); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/VariableLengthIntBufferTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/nodes/serial/VariableLengthIntBufferTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +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.serial; - -import java.nio.*; - -import org.junit.*; - -import com.oracle.truffle.api.nodes.serial.*; - -public class VariableLengthIntBufferTest { - - private VariableLengthIntBuffer buf; - - @Before - public void setUp() { - buf = new VariableLengthIntBuffer(ByteBuffer.allocate(512)); - } - - @After - public void tearDown() { - buf = null; - } - - @Test - public void testPutNull() { - buf.put(VariableLengthIntBuffer.NULL); - assertBytes(0xFF); - } - - @Test - public void testPutByteCornerCase0() { - buf.put(0x00); // 0 - assertBytes(0x00); - } - - @Test - public void testPutByteCornerCase1() { - buf.put(0x7F); // 127 - assertBytes(0x7F); - } - - @Test - public void testPutByteCornerCase2() { - buf.put(0x3FFF_FFFF); - assertBytes(0xBF, 0xFF, 0xFF, 0xFF); - } - - @Test(expected = IllegalArgumentException.class) - public void testPutByteCornerCase3() { - buf.put(0x4000_0000); // out of encodeable - } - - @Test - public void testGetNull() { - create(0xFF); - assertGet(VariableLengthIntBuffer.NULL); - } - - @Test - public void testGetCornerCase0() { - create(0x00); - assertGet(0x00); - } - - @Test - public void testGetCornerCase1() { - create(0x7F); - assertGet(0x7F); - } - - @Test - public void testGetCornerCase2() { - create(0xBF, 0xFF, 0xFF, 0xFF); - assertGet(0x3FFF_FFFF); - } - - @Test(expected = AssertionError.class) - public void testGetCornerCase3() { - create(0xFF, 0xFF, 0xFF, 0xFF); - assertGet(0x0); - } - - private void create(int... bytes) { - byte[] convBytes = new byte[bytes.length]; - for (int i = 0; i < bytes.length; i++) { - convBytes[i] = (byte) bytes[i]; - } - buf = new VariableLengthIntBuffer(convBytes); - } - - private void assertGet(int expected) { - Assert.assertEquals(expected, buf.get()); - } - - private void assertBytes(int... expectedBytes) { - byte[] actualBytes = buf.getBytes(); - Assert.assertEquals(expectedBytes.length, actualBytes.length); - for (int i = 0; i < expectedBytes.length; i++) { - Assert.assertTrue(actualBytes[i] == (byte) expectedBytes[i]); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package-info.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package-info.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ -/** - *

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 {@link com.oracle.truffle.api.test.instrument.InstrumentationTest}
  • - *
- * - * - */ -package com.oracle.truffle.api.test; - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/BytesSourceSectionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/BytesSourceSectionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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 static org.junit.Assert.*; - -import java.nio.charset.*; - -import org.junit.*; - -import com.oracle.truffle.api.source.*; - -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", new BytesDecoder.UTF8BytesDecoder()); - 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", new BytesDecoder.UTF8BytesDecoder()); - 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", new BytesDecoder.UTF8BytesDecoder()); - 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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceSectionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceSectionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +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.*; - -import org.junit.*; - -import com.oracle.truffle.api.source.*; - -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", null); - - 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); - } - - @Ignore - @Test - public void emptyLineTest0a() { - SourceSection section = emptyLineSource.createSection("test", 0, 0); - assertEquals(section.getEndLine(), 1); - assertEquals(section.getEndColumn(), 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); - } - - @Ignore - @Test - public void emptyLineTest2() { - SourceSection section = emptyLineSource.createSection("test", 1, 0); - assertNotNull(section); - assertEquals(section.getCode(), ""); - assertEquals(section.getCharIndex(), 1); - assertEquals(section.getCharLength(), 0); - 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(), ""); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTagTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTagTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +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.source; - -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.source.*; - -public class SourceTagTest { - - @Test - public void sourceTagTest() { - - // Private tag - final SourceTag testTag = new SourceTag() { - - public String name() { - return null; - } - - public String getDescription() { - return null; - } - }; - - // No sources exist with the private tag - assertEquals(Source.findSourcesTaggedAs(testTag).size(), 0); - - // Create a new source - final Source source = Source.fromText("test1 source", "test1 source"); - - // Initially has only the default tag - assertEquals(source.getSourceTags().size(), 1); - - assertTrue(source.getSourceTags().contains(Source.Tags.FROM_LITERAL)); - assertTrue(source.isTaggedAs(Source.Tags.FROM_LITERAL)); - assertTrue(Source.findSourcesTaggedAs(Source.Tags.FROM_LITERAL).contains(source)); - - assertFalse(source.isTaggedAs(testTag)); - assertEquals(Source.findSourcesTaggedAs(testTag).size(), 0); - - // Add a private tag - source.tagAs(testTag); - - // Now there are exactly two tags - assertEquals(source.getSourceTags().size(), 2); - - assertTrue(source.getSourceTags().contains(Source.Tags.FROM_LITERAL)); - assertTrue(source.isTaggedAs(Source.Tags.FROM_LITERAL)); - assertTrue(Source.findSourcesTaggedAs(Source.Tags.FROM_LITERAL).contains(source)); - - assertTrue(source.getSourceTags().contains(testTag)); - assertTrue(source.isTaggedAs(testTag)); - assertEquals(Source.findSourcesTaggedAs(testTag).size(), 1); - assertTrue(Source.findSourcesTaggedAs(testTag).contains(source)); - - // Add the private tag again - source.tagAs(testTag); - - // Nothing has changed - assertEquals(source.getSourceTags().size(), 2); - - assertTrue(source.getSourceTags().contains(Source.Tags.FROM_LITERAL)); - assertTrue(source.isTaggedAs(Source.Tags.FROM_LITERAL)); - assertTrue(Source.findSourcesTaggedAs(Source.Tags.FROM_LITERAL).contains(source)); - - assertTrue(source.getSourceTags().contains(testTag)); - assertTrue(source.isTaggedAs(testTag)); - assertEquals(Source.findSourcesTaggedAs(testTag).size(), 1); - assertTrue(Source.findSourcesTaggedAs(testTag).contains(source)); - } - - @Test - public void sourceListenerTest() { - - // Private tag - final SourceTag testTag = new SourceTag() { - - public String name() { - return null; - } - - public String getDescription() { - return null; - } - }; - - final int[] newSourceEvents = {0}; - final Source[] newSource = {null}; - - final int[] newTagEvents = {0}; - final Source[] taggedSource = {null}; - final SourceTag[] newTag = {null}; - - Source.addSourceListener(new SourceListener() { - - public void sourceCreated(Source source) { - newSourceEvents[0] = newSourceEvents[0] + 1; - newSource[0] = source; - } - - public void sourceTaggedAs(Source source, SourceTag tag) { - newTagEvents[0] = newTagEvents[0] + 1; - taggedSource[0] = source; - newTag[0] = tag; - } - }); - - // New source has a default tag applied. - // Get one event for the new source, another one when it gets tagged - final Source source = Source.fromText("testSource", "testSource"); - assertEquals(newSourceEvents[0], 1); - assertEquals(newSource[0], source); - assertEquals(newTagEvents[0], 1); - assertEquals(taggedSource[0], source); - assertEquals(newTag[0], Source.Tags.FROM_LITERAL); - - // reset - newSource[0] = null; - taggedSource[0] = null; - newTag[0] = null; - - // Add a tag; only get one event (the new tag) - source.tagAs(testTag); - assertEquals(newSourceEvents[0], 1); - assertEquals(newSource[0], null); - assertEquals(newTagEvents[0], 2); - assertEquals(taggedSource[0], source); - assertEquals(newTag[0], testTag); - - // Add the same tag; no events, and nothing changes. - source.tagAs(testTag); - assertEquals(newSourceEvents[0], 1); - assertEquals(newSource[0], null); - assertEquals(newTagEvents[0], 2); - assertEquals(taggedSource[0], source); - assertEquals(newTag[0], testTag); - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTextTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTextTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +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.*; - -import org.junit.*; - -import com.oracle.truffle.api.source.*; - -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); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyTextTest1() { - emptySource.getLineNumber(0); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyTextTest2() { - emptySource.getColumnNumber(0); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyTextTest3() { - emptySource.getLineNumber(-1); - } - - @Test(expected = IllegalArgumentException.class) - 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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AlwaysValidAssumptionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AlwaysValidAssumptionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AssumedValueTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/AssumedValueTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BinaryConditionProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BinaryConditionProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.utilities.*; - -@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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BranchProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/BranchProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CountingConditionProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CountingConditionProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.utilities.*; - -@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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CyclicAssumptionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/CyclicAssumptionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/ExactClassValueProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/ExactClassValueProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.utilities.*; - -@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 ExactClassValueProfile profile; - - @Before - public void create() { - profile = (ExactClassValueProfile) ValueProfile.createClassProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.isGeneric(), is(false)); - assertThat(profile.isUninitialized(), is(true)); - assertNull(profile.getCachedClass()); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOne(Object value) { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedClass(), expectedClass(value)); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwo(Object value0, Object value1) { - 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(profile.getCachedClass(), expectedClass); - assertThat(profile.isUninitialized(), is(false)); - assertThat(profile.isGeneric(), is(expectedClass == Object.class)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThree(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)); - - Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; - - assertEquals(profile.getCachedClass(), expectedClass); - assertThat(profile.isUninitialized(), is(false)); - assertThat(profile.isGeneric(), 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(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/IdentityValueProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/IdentityValueProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.utilities.*; - -@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 IdentityValueProfile profile; - - @Before - public void create() { - profile = (IdentityValueProfile) ValueProfile.createIdentityProfile(); - } - - @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 testProfileOne(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 testProfileTwo(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 testProfileThree(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 - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/NeverValidAssumptionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/NeverValidAssumptionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/PrimitiveValueProfileTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/PrimitiveValueProfileTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,945 +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 static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.*; -import org.junit.experimental.theories.*; -import org.junit.runner.*; - -import com.oracle.truffle.api.utilities.*; - -@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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/UnionAssumptionTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/UnionAssumptionTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /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 static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; - -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 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +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.*; - -import java.io.*; -import java.util.*; - -import org.junit.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.*; - -public class ImplicitExplicitExportTest { - private TruffleVM vm; - - @Before - public void initializeVM() { - vm = TruffleVM.newVM().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)); - } - - @Test - public void explicitExportFound() throws IOException { - // @formatter:off - vm.eval(L1, - "explicit.ahoj=42" - ); - Object ret = vm.eval(L3, - "return=ahoj" - ); - // @formatter:on - assertEquals("42", ret); - } - - @Test - public void implicitExportFound() throws IOException { - // @formatter:off - vm.eval(L1, - "implicit.ahoj=42" - ); - Object ret = vm.eval(L3, - "return=ahoj" - ); - // @formatter:on - assertEquals("42", ret); - } - - @Test - public void explicitExportPreferred2() throws IOException { - // @formatter:off - vm.eval(L1, - "implicit.ahoj=42" - ); - vm.eval(L2, - "explicit.ahoj=43" - ); - Object ret = vm.eval(L3, - "return=ahoj" - ); - // @formatter:on - assertEquals("Explicit import from L2 is used", "43", ret); - assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").invoke(null)); - } - - @Test - public void explicitExportPreferred1() throws IOException { - // @formatter:off - vm.eval(L1, - "explicit.ahoj=43" - ); - vm.eval(L2, - "implicit.ahoj=42" - ); - Object ret = vm.eval(L3, - "return=ahoj" - ); - // @formatter:on - assertEquals("Explicit import from L2 is used", "43", ret); - assertEquals("Global symbol is also 43", "43", vm.findGlobalSymbol("ahoj").invoke(null)); - } - - private abstract static class AbstractExportImportLanguage extends TruffleLanguage { - protected AbstractExportImportLanguage(Env env) { - super(env); - } - - private final Map explicit = new HashMap<>(); - private final Map implicit = new HashMap<>(); - - @Override - protected Object eval(Source code) throws IOException { - Properties p = new Properties(); - try (Reader r = code.getReader()) { - p.load(r); - } - Enumeration en = p.keys(); - while (en.hasMoreElements()) { - Object n = en.nextElement(); - if (n instanceof String) { - String k = (String) n; - if (k.startsWith("explicit.")) { - explicit.put(k.substring(9), p.getProperty(k)); - } - if (k.startsWith("implicit.")) { - implicit.put(k.substring(9), p.getProperty(k)); - } - if (k.equals("return")) { - return env().importSymbol(p.getProperty(k)); - } - } - } - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - if (explicit.containsKey(globalName)) { - return explicit.get(globalName); - } - if (!onlyExplicit && implicit.containsKey(globalName)) { - return implicit.get(globalName); - } - return null; - } - - @Override - protected Object getLanguageGlobal() { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return null; - } - - @Override - protected DebugSupportProvider getDebugSupport() { - return null; - } - } - - private static final String L1 = "application/x-test-import-export-1"; - private static final String L2 = "application/x-test-import-export-2"; - private 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 ExportImportLanguage1(Env env) { - super(env); - } - } - - @TruffleLanguage.Registration(mimeType = L2, name = "ImportExport2", version = "0") - public static final class ExportImportLanguage2 extends AbstractExportImportLanguage { - public ExportImportLanguage2(Env env) { - super(env); - } - } - - @TruffleLanguage.Registration(mimeType = L3, name = "ImportExport3", version = "0") - public static final class ExportImportLanguage3 extends AbstractExportImportLanguage { - public ExportImportLanguage3(Env env) { - super(env); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/TruffleVMSingleThreadedTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/TruffleVMSingleThreadedTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +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 java.io.*; -import java.net.*; - -import org.junit.*; - -import com.oracle.truffle.api.vm.*; - -public class TruffleVMSingleThreadedTest { - TruffleVM tvm; - - @Before - public void initInDifferentThread() throws InterruptedException { - final TruffleVM.Builder b = TruffleVM.newVM(); - 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, URISyntaxException { - tvm.eval(new URI("http://unknown.js")); - } - - @Test(expected = IllegalStateException.class) - public void evalString() throws IOException { - tvm.eval("text/javascript", "1 + 1"); - } - - @Test(expected = IllegalStateException.class) - public void evalReader() throws IOException { - try (StringReader sr = new StringReader("1 + 1")) { - tvm.eval("text/javascript", sr); - } - } - - @Test(expected = IllegalStateException.class) - public void findGlobalSymbol() { - tvm.findGlobalSymbol("doesNotExists"); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/.checkstyle_checks.xml --- a/graal/com.oracle.truffle.api/.checkstyle_checks.xml Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Assumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Assumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * An assumption is a global boolean flag that starts with the value true (i.e., the assumption is - * valid) and can subsequently be invalidated (using {@link Assumption#invalidate()}). Once - * invalidated, an assumption can never get valid again. Assumptions can be created using the - * {@link TruffleRuntime#createAssumption()} or the {@link TruffleRuntime#createAssumption(String)} - * method. The Truffle compiler has special knowledge of this class in order to produce efficient - * machine code for checking an assumption in case the assumption object is a compile time constant. - * Therefore, assumptions should be stored in final fields in Truffle nodes. - * - * All instances of classes implementing {@code Assumption} must be held in {@code final} fields for - * compiler optimizations to take effect. - */ -public interface Assumption { - - /** - * Checks that this assumption is still valid. The method throws an exception, if this is no - * longer the case. This method is preferred over the {@link #isValid()} method when writing - * guest language interpreter code. The catch block should perform a node rewrite (see - * {@link Node#replace(Node)}) with a node that no longer relies on the assumption. - * - * @throws InvalidAssumptionException If the assumption is no longer valid. - */ - void check() throws InvalidAssumptionException; - - /** - * Checks whether the assumption is still valid. - * - * @return a boolean value indicating the validity of the assumption - */ - boolean isValid(); - - /** - * Invalidates this assumption. Performs no operation, if the assumption is already invalid. - */ - void invalidate(); - - /** - * A name for the assumption that is used for debug output. - * - * @return the name of the assumption - */ - String getName(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Represents the target of a call. - */ -public interface CallTarget { - - /** - * Calls this target as a root method. - * - * @param arguments passed arguments as an object array - * @return the return result of the call - */ - Object call(Object... arguments); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Assertions about the code produced by the Truffle compiler. All operations have no effect when - * either executed in the interpreter or in the compiled code. The assertions are checked during - * code generation and the Truffle compiler produces for failing assertions a stack trace that - * identifies the code position of the assertion in the context of the current compilation. - * - */ -public class CompilerAsserts { - /** - * Assertion that this code position should never be reached during compilation. It can be used - * for exceptional code paths or rare code paths that should never be included in a compilation - * unit. See {@link CompilerDirectives#transferToInterpreter()} for the corresponding compiler - * directive. - */ - public static void neverPartOfCompilation() { - neverPartOfCompilation(""); - } - - /** - * Assertion that this code position should never be reached during compilation. It can be used - * for exceptional code paths or rare code paths that should never be included in a compilation - * unit. See {@link CompilerDirectives#transferToInterpreter()} for the corresponding compiler - * directive. - * - * @param message text associated with the bailout exception - */ - public static void neverPartOfCompilation(String message) { - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - */ - public static void compilationConstant(Object value) { - if (!CompilerDirectives.isCompilationConstant(value)) { - neverPartOfCompilation("Value is not compilation constant"); - } - } - - /** - * Assertion that the corresponding value is reduced to a constant during the initial partial - * evaluation phase. - * - * @param value the value that must be constant during compilation - */ - public static void partialEvaluationConstant(Object value) { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.lang.annotation.*; -import java.util.concurrent.*; - -/** - * Directives that influence the optimizations of the Truffle compiler. All of the operations have - * no effect when executed in the Truffle interpreter. - */ -public final class CompilerDirectives { - - public static final double LIKELY_PROBABILITY = 0.75; - public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY; - - public static final double SLOWPATH_PROBABILITY = 0.0001; - public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY; - - /** - * Directive for the compiler to discontinue compilation at this code position and instead - * insert a transfer to the interpreter. - */ - public static void transferToInterpreter() { - if (inInterpreter()) { - Truffle.getRuntime().notifyTransferToInterpreter(); - } - } - - /** - * Directive for the compiler to discontinue compilation at this code position and instead - * insert a transfer to the interpreter, invalidating the currently executing machine code. - */ - public static void transferToInterpreterAndInvalidate() { - if (inInterpreter()) { - Truffle.getRuntime().notifyTransferToInterpreter(); - } - } - - /** - * Returns a boolean value indicating whether the method is executed in the interpreter. - * - * @return {@code true} when executed in the interpreter, {@code false} in compiled code. - */ - public static boolean inInterpreter() { - return true; - } - - /** - * Returns a boolean value indicating whether the method is executed in the compiled code. - * - * @return {@code false} when executed in the interpreter, {@code true} in compiled code. - */ - public static boolean inCompiledCode() { - return false; - } - - /** - * Returns a boolean indicating whether or not a given value is seen as constant in optimized - * code. If this method is called in the interpreter this method will always return - * true. - * - * Note that optimizations that a compiler will apply to code that is conditional on - * isCompilationConstant may be limited. For this reason - * isCompilationConstant is not recommended for use to select between alternate - * implementations of functionality depending on whether a value is constant. Instead, it is - * intended for use as a diagnostic mechanism. - * - * @param value - * @return {@code true} when given value is seen as compilation constant, {@code false} if not - * compilation constant. - */ - public static boolean isCompilationConstant(Object value) { - return CompilerDirectives.inInterpreter(); - } - - /** - * Directive for the compiler that the given runnable should only be executed in the interpreter - * and ignored in the compiled code. - * - * @param runnable the closure that should only be executed in the interpreter - */ - public static void interpreterOnly(Runnable runnable) { - runnable.run(); - } - - /** - * Directive for the compiler that the given callable should only be executed in the - * interpreter. - * - * @param callable the closure that should only be executed in the interpreter - * @return the result of executing the closure in the interpreter and null in the compiled code - * @throws Exception If the closure throws an exception when executed in the interpreter. - */ - public static T interpreterOnly(Callable callable) throws Exception { - return callable.call(); - } - - /** - * Injects a probability for the given condition into the probability information of the - * immediately succeeding branch instruction for the condition. The probability must be a value - * between 0.0 and 1.0 (inclusive). The condition should not be a combined condition. - * - * Example usage immediately before an if statement (it specifies that the likelihood for a to - * be greater than b is 90%): - * - * - * if (injectBranchProbability(0.9, a > b)) { - * // ... - * } - * - * - * Example usage for a combined condition (it specifies that the likelihood for a to be greater - * than b is 90% and under the assumption that this is true, the likelihood for a being 0 is - * 10%): - * - * - * if (injectBranchProbability(0.9, a > b) && injectBranchProbability(0.1, a == 0)) { - * // ... - * } - * - * - * There are predefined constants for commonly used probabilities (see - * {@link #LIKELY_PROBABILITY} , {@link #UNLIKELY_PROBABILITY}, {@link #SLOWPATH_PROBABILITY}, - * {@link #FASTPATH_PROBABILITY} ). - * - * @param probability the probability value between 0.0 and 1.0 that should be injected - */ - public static boolean injectBranchProbability(double probability, boolean condition) { - assert probability >= 0.0 && probability <= 1.0; - return condition; - } - - /** - * Bails out of a compilation (e.g., for guest language features that should never be compiled). - * - * @param reason the reason for the bailout - */ - public static void bailout(String reason) { - } - - /** - * Marks fields that should be considered final for a Truffle compilation although they are not - * final while executing in the interpreter. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.FIELD}) - public @interface CompilationFinal { - } - - /** - * Marks a method that it is considered as a boundary for Truffle partial evaluation. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) - public @interface TruffleBoundary { - } - - /** - * Marks classes as value types. Reference comparisons (==) between instances of those classes - * have undefined semantics and can either return true or false. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.TYPE}) - public @interface ValueType { - } - - /** - * Ensures that the given object is not virtual, i.e., not removed by Escape Analysis at the - * point of this call. - * - * @param obj the object to exclude from Escape Analysis - */ - public static void materialize(Object obj) { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerOptions.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerOptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Allows options to be set to control the compilation of a specific {@link RootNode}, without - * creating a dependency on the specific compiler used. Options can be tested for support before - * setting. - */ -public interface CompilerOptions { - - boolean supportsOption(String name); - - void setOption(String name, Object value); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExactMath.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExactMath.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * This class contains methods that will be part of java.lang.Math starting with JDK 8. Until JDK 8 - * is release, we duplicate them here because they are generally useful for dynamic language - * implementations. - */ -public class ExactMath { - - public static int addExact(int x, int y) { - int r = x + y; - // HD 2-12 Overflow iff both arguments have the opposite sign of the result - if (((x ^ r) & (y ^ r)) < 0) { - throw new ArithmeticException("integer overflow"); - } - return r; - } - - public static long addExact(long x, long y) { - long r = x + y; - // HD 2-12 Overflow iff both arguments have the opposite sign of the result - if (((x ^ r) & (y ^ r)) < 0) { - throw new ArithmeticException("long overflow"); - } - return r; - } - - public static int subtractExact(int x, int y) { - int r = x - y; - // HD 2-12 Overflow iff the arguments have different signs and - // the sign of the result is different than the sign of x - if (((x ^ y) & (x ^ r)) < 0) { - throw new ArithmeticException("integer overflow"); - } - return r; - } - - public static long subtractExact(long x, long y) { - long r = x - y; - // HD 2-12 Overflow iff the arguments have different signs and - // the sign of the result is different than the sign of x - if (((x ^ y) & (x ^ r)) < 0) { - throw new ArithmeticException("long overflow"); - } - return r; - } - - public static int multiplyExact(int x, int y) { - long r = (long) x * (long) y; - if ((int) r != r) { - throw new ArithmeticException("long overflow"); - } - return (int) r; - } - - public static long multiplyExact(long x, long y) { - long r = x * y; - long ax = Math.abs(x); - long ay = Math.abs(y); - if (((ax | ay) >>> 31 != 0)) { - // Some bits greater than 2^31 that might cause overflow - // Check the result using the divide operator - // and check for the special case of Long.MIN_VALUE * -1 - if (((y != 0) && (r / y != x)) || (x == Long.MIN_VALUE && y == -1)) { - throw new ArithmeticException("long overflow"); - } - } - return r; - } - - public static int multiplyHigh(int x, int y) { - long r = (long) x * (long) y; - return (int) (r >> 32); - } - - public static int multiplyHighUnsigned(int x, int y) { - long xl = x & 0xFFFFFFFFL; - long yl = y & 0xFFFFFFFFL; - long r = xl * yl; - return (int) (r >> 32); - } - - public static long multiplyHigh(long x, long y) { - // Checkstyle: stop - long x0, y0, z0; - long x1, y1, z1, z2, t; - // Checkstyle: resume - - x0 = x & 0xFFFFFFFFL; - x1 = x >> 32; - - y0 = y & 0xFFFFFFFFL; - y1 = y >> 32; - - z0 = x0 * y0; - t = x1 * y0 + (z0 >>> 32); - z1 = t & 0xFFFFFFFFL; - z2 = t >> 32; - z1 += x0 * y1; - - return x1 * y1 + z2 + (z1 >> 32); - } - - public static long multiplyHighUnsigned(long x, long y) { - // Checkstyle: stop - long x0, y0, z0; - long x1, y1, z1, z2, t; - // Checkstyle: resume - - x0 = x & 0xFFFFFFFFL; - x1 = x >>> 32; - - y0 = y & 0xFFFFFFFFL; - y1 = y >>> 32; - - z0 = x0 * y0; - t = x1 * y0 + (z0 >>> 32); - z1 = t & 0xFFFFFFFFL; - z2 = t >>> 32; - z1 += x0 * y1; - - return x1 * y1 + z2 + (z1 >>> 32); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl.*; - -/** - * Access to information and basic services in the runtime context for a Truffle-implemented guest - * language. - */ -public abstract class ExecutionContext { - - protected ExecutionContext() { - } - - /** - * Get compiler options specific to this ExecutionContext. - */ - public CompilerOptions getCompilerOptions() { - return DefaultCompilerOptions.INSTANCE; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Accepts the execution count of a loop that is a child of this node. The optimization heuristics - * can use the loop count to guide compilation and inlining. - */ -public interface LoopCountReceiver { - - void reportLoopCount(int count); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/OptimizationFailedException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/OptimizationFailedException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -public class OptimizationFailedException extends RuntimeException { - - private final RootCallTarget callTarget; - - public OptimizationFailedException(Throwable cause, RootCallTarget callTarget) { - super(cause); - this.callTarget = callTarget; - } - - public RootCallTarget getCallTarget() { - return callTarget; - } - - private static final long serialVersionUID = -8797188744430210785L; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * An observer that is notified whenever a child node is replaced. - */ -public interface ReplaceObserver { - - /** - * Returns true if the event is consumed and no parent nodes should be notified by - * for replaces. Returns false if the parent {@link Node} or {@link CallTarget} - * should get notified. - */ - boolean nodeReplaced(Node oldNode, Node newNode, CharSequence reason); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Represents the target of a call to a {@link RootNode}, i.e., to another tree of nodes. Instances - * of this class can be created using {@link TruffleRuntime#createCallTarget(RootNode)}. - */ -public interface RootCallTarget extends CallTarget { - - RootNode getRootNode(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.lang.reflect.*; -import java.security.*; - -import com.oracle.truffle.api.impl.*; - -/** - * Class for obtaining the Truffle runtime singleton object of this virtual machine. - */ -public class Truffle { - - private static final TruffleRuntime RUNTIME = initRuntime(); - - /** - * Gets the singleton {@link TruffleRuntime} object. - */ - public static TruffleRuntime getRuntime() { - return RUNTIME; - } - - private static TruffleRuntime initRuntime() { - if (TruffleOptions.ForceInterpreter) { - /* - * Force Truffle to run in interpreter mode even if we have a specialized implementation - * of TruffleRuntime available. - */ - return new DefaultTruffleRuntime(); - } - - return AccessController.doPrivileged(new PrivilegedAction() { - public TruffleRuntime run() { - TruffleRuntimeAccess access = null; - Class servicesClass = null; - try { - servicesClass = Class.forName("com.oracle.jvmci.service.Services"); - } catch (ClassNotFoundException e) { - // JVMCI is unavailable - e.printStackTrace(); - } catch (IllegalArgumentException ex) { - throw new IllegalStateException("jvmci service found but yields error", ex); - } - if (servicesClass != null) { - try { - Method m = servicesClass.getDeclaredMethod("loadSingle", Class.class, boolean.class); - access = (TruffleRuntimeAccess) m.invoke(null, TruffleRuntimeAccess.class, false); - } catch (Throwable e) { - // Fail fast for other errors - throw (InternalError) new InternalError().initCause(e); - } - } - // TODO: try standard ServiceLoader? - if (access != null) { - return access.getRuntime(); - } - return new DefaultTruffleRuntime(); - } - }); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import java.lang.annotation.*; -import java.lang.reflect.*; - -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.*; -import com.oracle.truffle.api.vm.TruffleVM.Language; - -/** - * An entry point for everyone who wants to implement a Truffle based language. By providing - * implementation of this type and registering it using {@link Registration} annotation, your - * language becomes accessible to users of the {@link TruffleVM Truffle virtual machine} - all they - * will need to do is to include your JAR into their application and all the Truffle goodies (multi - * language support, multitenant hosting, debugging, etc.) will be made available to them. - */ -public abstract class TruffleLanguage { - private final Env env; - - /** - * Constructor to be called by subclasses. - * - * @param env language environment that will be available via {@link #env()} method to - * subclasses. - */ - protected TruffleLanguage(Env env) { - this.env = env; - } - - /** - * The annotation to use to register your language to the {@link TruffleVM Truffle} system. By - * annotating your implementation of {@link TruffleLanguage} by this annotation you are just a - * one JAR drop to the class path away from your users. Once they include your JAR in - * their application, your language will be available to the {@link TruffleVM Truffle virtual - * machine}. - */ - @Retention(RetentionPolicy.SOURCE) - @Target(ElementType.TYPE) - public @interface Registration { - /** - * Unique name of your language. This name will be exposed to users via the - * {@link Language#getName()} getter. - * - * @return identifier of your language - */ - String name(); - - /** - * Unique string identifying the language version. This name will be exposed to users via - * the {@link Language#getVersion()} getter. - * - * @return version of your language - */ - String version(); - - /** - * List of MIME types associated with your language. Users will use them (directly or - * indirectly) when {@link TruffleVM#eval(java.lang.String, java.lang.String) executing} - * their code snippets or their {@link TruffleVM#eval(java.net.URI) files}. - * - * @return array of MIME types assigned to your language files - */ - String[] mimeType(); - } - - protected final Env env() { - if (this.env == null) { - throw new NullPointerException("Accessing env before initialization is finished"); - } - return this.env; - } - - protected abstract Object eval(Source code) throws IOException; - - /** - * Called when some other language is seeking for a global symbol. This method is supposed to do - * lazy binding, e.g. there is no need to export symbols in advance, it is fine to wait until - * somebody asks for it (by calling this method). - *

- * The exported object can either be TruffleObject (e.g. a native object from the - * other language) to support interoperability between languages, {@link String} or one of Java - * primitive wrappers ( {@link Integer}, {@link Double}, {@link Short}, {@link Boolean}, etc.). - *

- * The way a symbol becomes exported is language dependent. In general it is preferred - * to make the export explicit - e.g. call some function or method to register an object under - * specific name. Some languages may however decide to support implicit export of symbols (for - * example from global scope, if they have one). However explicit exports should always be - * preferred. Implicitly exported object of some name should only be used when there is no - * explicit export under such globalName. To ensure so the infrastructure first - * asks all known languages for onlyExplicit symbols and only when none is found, - * it does one more round with onlyExplicit set to false. - * - * @param globalName the name of the global symbol to find - * @param onlyExplicit should the language seek for implicitly exported object or only consider - * the explicitly exported ones? - * @return an exported object or null, if the symbol does not represent anything - * meaningful in this language - */ - protected abstract Object findExportedSymbol(String globalName, boolean onlyExplicit); - - /** - * Returns global object for the language. - *

- * The object is expected to be TruffleObject (e.g. a native object from the other - * language) but technically it can be one of Java primitive wrappers ({@link Integer}, - * {@link Double}, {@link Short}, etc.). - * - * @return the global object or null if the language does not support such concept - */ - protected abstract Object getLanguageGlobal(); - - /** - * Checks whether the object is provided by this language. - * - * @param object the object to check - * @return true if this language can deal with such object in native way - */ - protected abstract boolean isObjectOfLanguage(Object object); - - protected abstract ToolSupportProvider getToolSupport(); - - protected abstract DebugSupportProvider getDebugSupport(); - - /** - * Represents execution environment of the {@link TruffleLanguage}. Each active - * {@link TruffleLanguage} receives instance of the environment before any code is executed upon - * it. The environment has knowledge of all active languages and can exchange symbols between - * them. - */ - public static final class Env { - private final TruffleVM vm; - private final TruffleLanguage lang; - private final Reader in; - private final Writer err; - private final Writer out; - - Env(TruffleVM vm, Constructor langConstructor, Writer out, Writer err, Reader in) { - this.vm = vm; - this.in = in; - this.err = err; - this.out = out; - try { - this.lang = (TruffleLanguage) langConstructor.newInstance(this); - } catch (Exception ex) { - throw new IllegalStateException("Cannot construct language " + langConstructor.getDeclaringClass().getName(), ex); - } - } - - /** - * Asks the environment to go through other registered languages and find whether they - * export global symbol of specified name. The expected return type is either - * TruffleObject, or one of wrappers of Java primitive types ({@link Integer}, - * {@link Double}). - * - * @param globalName the name of the symbol to search for - * @return object representing the symbol or null - */ - public Object importSymbol(String globalName) { - return API.importSymbol(vm, lang, globalName); - } - - /** - * Input associated with this {@link TruffleVM}. - * - * @return reader, never null - */ - public Reader stdIn() { - return in; - } - - /** - * Standard output writer for this {@link TruffleVM}. - * - * @return writer, never null - */ - public Writer stdOut() { - return out; - } - - /** - * Standard error writer for this {@link TruffleVM}. - * - * @return writer, never null - */ - public Writer stdErr() { - return err; - } - } - - private static final AccessAPI API = new AccessAPI(); - - private static final class AccessAPI extends Accessor { - @Override - protected TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - Env env = new Env(vm, langClazz, stdOut, stdErr, stdIn); - return env.lang; - } - - @Override - public Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { - return super.importSymbol(vm, queryingLang, globalName); - } - - @Override - protected Object eval(TruffleLanguage l, Source s) throws IOException { - return l.eval(s); - } - - @Override - protected Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return l.findExportedSymbol(globalName, onlyExplicit); - } - - @Override - protected Object languageGlobal(TruffleLanguage l) { - return l.getLanguageGlobal(); - } - - @Override - protected ToolSupportProvider getToolSupport(TruffleLanguage l) { - return l.getToolSupport(); - } - - @Override - protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { - return l.getDebugSupport(); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.security.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Class containing general Truffle options. - */ -public class TruffleOptions { - - /** - * Force truffle to run in interpreter mode. - *

- * Can be set with {@code -Dtruffle.ForceInterpreter=true}. - */ - public static final boolean ForceInterpreter = Boolean.getBoolean("truffle.ForceInterpreter"); - - /** - * Enables/disables the rewriting of traces in the Truffle runtime to stdout. - *

- * Can be set with {@code -Dtruffle.TraceRewrites=true}. - */ - public static final boolean TraceRewrites; - - /** - * Enables the generation of detailed rewrite reasons. Enabling this may introduce some overhead - * for rewriting nodes. - *

- * Can be set with {@code -Dtruffle.DetailedRewriteReasons=true}. - */ - public static final boolean DetailedRewriteReasons; - - /** - * Filters rewrites that do not contain the given string in the qualified name of the source or - * target class hierarchy. - *

- * Can be set with {@code -Dtruffle.TraceRewritesFilterClass=name}. - */ - public static String TraceRewritesFilterClass; - - /** - * Filters rewrites which does not contain the {@link NodeCost} in its source {@link NodeInfo}. - * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. - *

- * Can be set with - * {@code -Dtruffle.TraceRewritesFilterFromCost=NONE|MONOMORPHIC|POLYMORPHIC|MEGAMORPHIC}. - */ - public static NodeCost TraceRewritesFilterFromCost; - - /** - * Filters rewrites which does not contain the {@link NodeCost} in its target {@link NodeInfo}. - * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. - *

- * Can be set with - * {@code -Dtruffle.TraceRewritesFilterToKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. - */ - public static NodeCost TraceRewritesFilterToCost; - - /** - * Enables the dumping of Node creations and AST rewrites in JSON format. - *

- * Can be set with {@code -Dtruffle.TraceASTJSON=true}. - */ - public static final boolean TraceASTJSON; - - private static NodeCost parseNodeInfoKind(String kind) { - if (kind == null) { - return null; - } - - return NodeCost.valueOf(kind); - } - - static { - final boolean[] values = new boolean[3]; - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - values[0] = Boolean.getBoolean("truffle.TraceRewrites"); - TraceRewritesFilterClass = System.getProperty("truffle.TraceRewritesFilterClass"); - TraceRewritesFilterFromCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromCost")); - TraceRewritesFilterToCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToCost")); - values[1] = Boolean.getBoolean("truffle.DetailedRewriteReasons"); - values[2] = Boolean.getBoolean("truffle.TraceASTJSON"); - return null; - } - }); - TraceRewrites = values[0]; - DetailedRewriteReasons = values[1]; - TraceASTJSON = values[2]; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.util.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Interface representing a Truffle runtime object. The runtime is responsible for creating call - * targets and performing optimizations for them. - */ -public interface TruffleRuntime { - - /** - * Name describing this runtime implementation for debugging purposes. - * - * @return the name as a String - */ - String getName(); - - /** - * Creates a new call target for a given root node. - * - * @param rootNode the root node whose - * {@link RootNode#execute(com.oracle.truffle.api.frame.VirtualFrame)} method - * represents the entry point - * @return the new call target object - */ - RootCallTarget createCallTarget(RootNode rootNode); - - /** - * Creates a new runtime specific version of {@link DirectCallNode}. - * - * @param target the direct {@link CallTarget} to call - * @return the new call node - */ - DirectCallNode createDirectCallNode(CallTarget target); - - /** - * Experimental API. May change without notice. - */ - LoopNode createLoopNode(RepeatingNode body); - - /** - * Creates a new runtime specific version of {@link IndirectCallNode}. - * - * @return the new call node - */ - IndirectCallNode createIndirectCallNode(); - - /** - * Creates a new assumption object that can be checked and invalidated. - * - * @return the newly created assumption object - */ - Assumption createAssumption(); - - /** - * Creates a new assumption object with a given name that can be checked and invalidated. - * - * @param name the name for the new assumption - * @return the newly created assumption object - */ - Assumption createAssumption(String name); - - /** - * Creates a new virtual frame object that can be used to store values and is potentially - * optimizable by the runtime. - * - * @return the newly created virtual frame object - */ - VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor); - - /** - * Creates a new materialized frame object that can be used to store values. - * - * @return the newly created materialized frame object - */ - MaterializedFrame createMaterializedFrame(Object[] arguments); - - /** - * Creates a new materialized frame object with the given frame descriptor that can be used to - * store values. - * - * @param frameDescriptor the frame descriptor describing this frame's values - * @return the newly created materialized frame object - */ - MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor); - - /** - * Creates an object which allows you to test for support of and set options specific for this - * runtime. - * - * @return the newly created compiler options object - */ - CompilerOptions createCompilerOptions(); - - /** - * Accesses the current stack, i.e., the contents of the {@link Frame}s and the associated - * {@link CallTarget}s. Iteration starts at the caller frame, i.e., it does not include the - * current frame. - * - * Iteration continues as long as {@link FrameInstanceVisitor#visitFrame}, which is invoked for - * every {@link FrameInstance}, returns null. Any non-null result of the visitor indicates that - * frame iteration should stop. - * - * @param visitor the visitor that is called for every matching frame. - * @return the last result returned by the visitor (which is non-null to indicate that iteration - * should stop), or null if the whole stack was iterated. - */ - T iterateFrames(FrameInstanceVisitor visitor); - - /** - * Accesses the caller frame. This is a convenience method that returns the first frame that is - * passed to the visitor of {@link #iterateFrames}. - */ - FrameInstance getCallerFrame(); - - /** - * Accesses the current frame, i.e., the frame of the closest {@link CallTarget}. It is - * important to note that this {@link FrameInstance} supports only slow path access. - */ - FrameInstance getCurrentFrame(); - - /** - * Requests a capability from the runtime. - * - * @param capability the type of the interface representing the capability - * @return an implementation of the capability or {@code null} if the runtime does not offer it - */ - T getCapability(Class capability); - - /** - * Returns a list of all still referenced {@link RootCallTarget} instances that were created - * using {@link #createCallTarget(RootNode)}. - */ - Collection getCallTargets(); - - /** - * Internal API method. Do not use. - */ - void notifyTransferToInterpreter(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * A service that provides access to a {@link TruffleRuntime} implementation. - */ -public interface TruffleRuntimeAccess { - - /** - * Gets the {@link TruffleRuntime} implementation available via this access object. - */ - TruffleRuntime getRuntime(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TypedObject.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TypedObject.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -public interface TypedObject { - - Object getTypeIdentifier(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.debug; - -public class DebugSupportException extends Exception { - - private static final long serialVersionUID = 3039074861617372741L; - - public DebugSupportException(String string) { - super(string); - } - - public DebugSupportException(Exception ex) { - super(ex); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportProvider.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportProvider.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.debug; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Access to language-specific information and execution services to enable debugging. - */ -public interface DebugSupportProvider extends ToolSupportProvider { - - /** - * Runs source code. - * - * @param source code - * @throws DebugSupportException if unable to run successfully - */ - void run(Source source) throws DebugSupportException; - - /** - * Runs source code in a halted execution context, or at top level. - * - * @param source the code to run - * @param node node where execution halted, {@code null} if no execution context - * @param mFrame frame where execution halted, {@code null} if no execution context - * @return result of running the code in the context, or at top level if no execution context. - * @throws DebugSupportException if the evaluation cannot be performed - */ - Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugSupportException; - - /** - * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot} - * that, when executed, computes the result of a textual expression in the language; used to - * create an - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @param expr a guest language expression - * @param resultListener optional listener for the result of each evaluation. - * @return a new factory - * @throws DebugSupportException if the factory cannot be created, for example if the expression - * is badly formed. - */ - AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugSupportException; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -/** - * Represents a frame containing values of local variables of the guest language. Instances of this - * type must not be stored in a field or cast to {@link java.lang.Object}. - */ -public interface Frame { - - /** - * @return the object describing the layout of this frame - */ - FrameDescriptor getFrameDescriptor(); - - /** - * Retrieves the arguments object from this frame. The runtime assumes that the arguments object - * is never null. - * - * @return the arguments used when calling this method - */ - Object[] getArguments(); - - /** - * Read access to a local variable of type {@link Object}. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - Object getObject(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type {@link Object}. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setObject(FrameSlot slot, Object value); - - /** - * Read access to a local variable of type byte. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - * @throws FrameSlotTypeException - */ - byte getByte(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type byte. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - - void setByte(FrameSlot slot, byte value); - - /** - * Read access to a local variable of type boolean. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type boolean. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setBoolean(FrameSlot slot, boolean value); - - /** - * Read access to a local variable of type int. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - int getInt(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type int. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setInt(FrameSlot slot, int value); - - /** - * Read access to a local variable of type long. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - long getLong(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type long. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setLong(FrameSlot slot, long value); - - /** - * Read access to a local variable of type float. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - float getFloat(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type float. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setFloat(FrameSlot slot, float value); - - /** - * Read access to a local variable of type double. - * - * @param slot the slot of the local variable - * @return the current value of the local variable - */ - double getDouble(FrameSlot slot) throws FrameSlotTypeException; - - /** - * Write access to a local variable of type double. - * - * @param slot the slot of the local variable - * @param value the new value of the local variable - */ - void setDouble(FrameSlot slot, double value); - - /** - * Read access to a local variable of any type. - * - * @param slot the slot of the local variable - * @return the current value of the local variable or defaultValue if unset - */ - Object getValue(FrameSlot slot); - - /** - * Materializes this frame, which allows it to be stored in a field or cast to - * {@link java.lang.Object}. - * - * @return the new materialized frame - */ - MaterializedFrame materialize(); - - /** - * Check whether the given {@link FrameSlot} is of type object. - */ - boolean isObject(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type byte. - */ - boolean isByte(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type boolean. - */ - boolean isBoolean(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type int. - */ - boolean isInt(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type long. - */ - boolean isLong(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type float. - */ - boolean isFloat(FrameSlot slot); - - /** - * Check whether the given {@link FrameSlot} is of type double. - */ - boolean isDouble(FrameSlot slot); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -import java.util.*; - -import com.oracle.truffle.api.*; - -/** - * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such - * descriptor. - */ -public final class FrameDescriptor implements Cloneable { - - private final Object defaultValue; - private final ArrayList slots; - private final HashMap identifierToSlotMap; - private Assumption version; - private HashMap identifierToNotInFrameAssumptionMap; - - public FrameDescriptor() { - this(null); - } - - public FrameDescriptor(Object defaultValue) { - this.defaultValue = defaultValue; - slots = new ArrayList<>(); - identifierToSlotMap = new HashMap<>(); - version = createVersion(); - } - - public static FrameDescriptor create() { - return new FrameDescriptor(); - } - - public static FrameDescriptor create(Object defaultValue) { - return new FrameDescriptor(defaultValue); - } - - public FrameSlot addFrameSlot(Object identifier) { - return addFrameSlot(identifier, null, FrameSlotKind.Illegal); - } - - public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) { - return addFrameSlot(identifier, null, kind); - } - - public FrameSlot addFrameSlot(Object identifier, Object info, FrameSlotKind kind) { - CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations."); - assert !identifierToSlotMap.containsKey(identifier); - FrameSlot slot = new FrameSlot(this, identifier, info, slots.size(), kind); - slots.add(slot); - identifierToSlotMap.put(identifier, slot); - updateVersion(); - invalidateNotInFrameAssumption(identifier); - return slot; - } - - public FrameSlot findFrameSlot(Object identifier) { - return identifierToSlotMap.get(identifier); - } - - public FrameSlot findOrAddFrameSlot(Object identifier) { - FrameSlot result = findFrameSlot(identifier); - if (result != null) { - return result; - } - return addFrameSlot(identifier); - } - - public FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind) { - FrameSlot result = findFrameSlot(identifier); - if (result != null) { - return result; - } - return addFrameSlot(identifier, kind); - } - - public FrameSlot findOrAddFrameSlot(Object identifier, Object info, FrameSlotKind kind) { - FrameSlot result = findFrameSlot(identifier); - if (result != null) { - return result; - } - return addFrameSlot(identifier, info, kind); - } - - public void removeFrameSlot(Object identifier) { - CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations."); - assert identifierToSlotMap.containsKey(identifier); - slots.remove(identifierToSlotMap.get(identifier)); - identifierToSlotMap.remove(identifier); - updateVersion(); - getNotInFrameAssumption(identifier); - } - - public int getSize() { - return slots.size(); - } - - public List getSlots() { - return Collections.unmodifiableList(slots); - } - - /** - * Retrieve the list of all the identifiers associated with this frame descriptor. - * - * @return the list of all the identifiers in this frame descriptor - */ - public Set getIdentifiers() { - return Collections.unmodifiableSet(identifierToSlotMap.keySet()); - } - - public FrameDescriptor copy() { - FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue); - for (int i = 0; i < this.getSlots().size(); i++) { - Object identifier = this.getSlots().get(i).getIdentifier(); - clonedFrameDescriptor.addFrameSlot(identifier); - } - return clonedFrameDescriptor; - } - - public FrameDescriptor shallowCopy() { - FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue); - clonedFrameDescriptor.slots.addAll(slots); - clonedFrameDescriptor.identifierToSlotMap.putAll(identifierToSlotMap); - return clonedFrameDescriptor; - } - - void updateVersion() { - version.invalidate(); - version = createVersion(); - } - - public Assumption getVersion() { - return version; - } - - private static Assumption createVersion() { - return Truffle.getRuntime().createAssumption("frame version"); - } - - public Object getDefaultValue() { - return defaultValue; - } - - public Assumption getNotInFrameAssumption(Object identifier) { - if (identifierToSlotMap.containsKey(identifier)) { - throw new IllegalArgumentException("Cannot get not-in-frame assumption for existing frame slot!"); - } - - if (identifierToNotInFrameAssumptionMap == null) { - identifierToNotInFrameAssumptionMap = new HashMap<>(); - } else { - Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier); - if (assumption != null) { - return assumption; - } - } - Assumption assumption = Truffle.getRuntime().createAssumption("not in frame: " + identifier); - identifierToNotInFrameAssumptionMap.put(identifier, assumption); - return assumption; - } - - private void invalidateNotInFrameAssumption(Object identifier) { - if (identifierToNotInFrameAssumptionMap != null) { - Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier); - if (assumption != null) { - assumption.invalidate(); - identifierToNotInFrameAssumptionMap.remove(identifier); - } - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("FrameDescriptor@").append(Integer.toHexString(hashCode())); - sb.append("{"); - boolean comma = false; - for (FrameSlot slot : slots) { - if (comma) { - sb.append(", "); - } else { - comma = true; - } - sb.append(slot.getIndex()).append(":").append(slot.getIdentifier()); - } - sb.append("}"); - return sb.toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -public interface FrameInstance { - - public static enum FrameAccess { - NONE, - READ_ONLY, - READ_WRITE, - MATERIALIZE - } - - Frame getFrame(FrameAccess access, boolean slowPath); - - boolean isVirtualFrame(); - - Node getCallNode(); - - CallTarget getCallTarget(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstanceVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstanceVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -import com.oracle.truffle.api.*; - -/** - * Callback interface for {@link TruffleRuntime#iterateFrames}. Implementations of - * {@link #visitFrame} return null to indicate that frame iteration should continue and the next - * caller frame should be visited; and return any non-null value to indicate that frame iteration - * should stop. - */ -public interface FrameInstanceVisitor { - - T visitFrame(FrameInstance frameInstance); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * A slot in a frame that can store a value of a given type. - */ -public final class FrameSlot implements Cloneable { - - private final FrameDescriptor descriptor; - private final Object identifier; - private final Object info; - private final int index; - @CompilationFinal private FrameSlotKind kind; - - public FrameSlot(FrameDescriptor descriptor, Object identifier, Object info, int index, FrameSlotKind kind) { - this.descriptor = descriptor; - this.identifier = identifier; - this.info = info; - this.index = index; - this.kind = kind; - } - - public Object getIdentifier() { - return identifier; - } - - public Object getInfo() { - return info; - } - - public int getIndex() { - return index; - } - - public FrameSlotKind getKind() { - return kind; - } - - public void setKind(final FrameSlotKind kind) { - if (this.kind != kind) { - CompilerDirectives.transferToInterpreter(); - this.kind = kind; - this.descriptor.updateVersion(); - } - } - - @Override - public String toString() { - return "[" + index + "," + identifier + "," + kind + "]"; - } - - public FrameDescriptor getFrameDescriptor() { - return this.descriptor; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -public enum FrameSlotKind { - Object, - Illegal, - Long, - Int, - Double, - Float, - Boolean, - Byte; - - public final byte tag; - - private FrameSlotKind() { - this.tag = (byte) ordinal(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -import com.oracle.truffle.api.nodes.*; - -/** - * Exception thrown if the frame slot type does not match the access type. - */ -public final class FrameSlotTypeException extends SlowPathException { - - private static final long serialVersionUID = 6972120475215757452L; - - public FrameSlotTypeException() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -public final class FrameUtil { - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getObject(FrameSlot) - */ - public static Object getObjectSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getObject(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getByte(FrameSlot) - */ - public static byte getByteSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getByte(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getBoolean(FrameSlot) - */ - public static boolean getBooleanSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getBoolean(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getInt(FrameSlot) - */ - public static int getIntSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getInt(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getLong(FrameSlot) - */ - public static long getLongSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getLong(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getDouble(FrameSlot) - */ - public static double getDoubleSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getDouble(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - /** - * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by - * a guard or statically known). - * - * @param frameSlot the slot of the variable - * @throws IllegalStateException if the slot kind does not match - * @see Frame#getFloat(FrameSlot) - */ - public static float getFloatSafe(Frame frame, FrameSlot frameSlot) { - try { - return frame.getFloat(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -/** - * Represents a materialized frame containing values of local variables of the guest language. It - * can be created using the {@link VirtualFrame#materialize()} method. Instances of this type are - * the only frame instances that may be stored in fields or cast to {@link java.lang.Object}. - */ -public interface MaterializedFrame extends Frame { - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/VirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/VirtualFrame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame; - -/** - * Represents a frame containing values of local variables of the guest language. Instances of this - * type must not be stored in a field or cast to {@link java.lang.Object}. If this is necessary, the - * frame must be explicitly converted into a materialized frame using the - * {@link VirtualFrame#materialize()} method. - */ -public interface VirtualFrame extends Frame { -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; - -public abstract class AbstractAssumption implements Assumption { - - protected final String name; - protected boolean isValid; - - protected AbstractAssumption(String name) { - this.name = name; - this.isValid = true; - } - - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return "Assumption(" + (isValid ? "valid" : "invalid") + ", name=" + name + ")"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.*; - -/** - * Communication between TruffleVM and TruffleLanguage API/SPI. - */ -public abstract class Accessor { - private static Accessor API; - private static Accessor SPI; - static { - TruffleLanguage lng = new TruffleLanguage(null) { - @Override - protected Object eval(Source code) throws IOException { - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal() { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return null; - } - - @Override - protected DebugSupportProvider getDebugSupport() { - return null; - } - }; - lng.hashCode(); - } - - protected Accessor() { - if (this.getClass().getSimpleName().endsWith("API")) { - if (API != null) { - throw new IllegalStateException(); - } - API = this; - } else { - if (SPI != null) { - throw new IllegalStateException(); - } - SPI = this; - } - } - - protected TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - return API.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); - } - - protected Object eval(TruffleLanguage l, Source s) throws IOException { - return API.eval(l, s); - } - - protected Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { - return SPI.importSymbol(vm, queryingLang, globalName); - } - - protected Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return API.findExportedSymbol(l, globalName, onlyExplicit); - } - - protected Object languageGlobal(TruffleLanguage l) { - return API.languageGlobal(l); - } - - protected ToolSupportProvider getToolSupport(TruffleLanguage l) { - return API.getToolSupport(l); - } - - protected DebugSupportProvider getDebugSupport(TruffleLanguage l) { - return API.getDebugSupport(l); - } - - protected Object invoke(Object obj, Object[] args) throws IOException { - for (SymbolInvoker si : ServiceLoader.load(SymbolInvoker.class)) { - return si.invoke(obj, args); - } - throw new IOException("No symbol invoker found!"); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This is an implementation-specific class. Do not use or instantiate it. Instead, use - * {@link TruffleRuntime#createAssumption()} to create an {@link Assumption}. - */ -final class DefaultAssumption extends AbstractAssumption { - - DefaultAssumption(String name) { - super(name); - } - - @Override - public void check() throws InvalidAssumptionException { - if (!isValid) { - throw new InvalidAssumptionException(); - } - } - - @Override - public void invalidate() { - isValid = false; - } - - @Override - public boolean isValid() { - return isValid; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This is an implementation-specific class. Do not use or instantiate it. Instead, use - * {@link TruffleRuntime#createCallTarget(RootNode)} to create a {@link RootCallTarget}. - */ -public class DefaultCallTarget implements RootCallTarget { - - private final RootNode rootNode; - - protected DefaultCallTarget(RootNode function) { - this.rootNode = function; - this.rootNode.adoptChildren(); - this.rootNode.applyInstrumentation(); - } - - @Override - public String toString() { - return rootNode.toString(); - } - - public final RootNode getRootNode() { - return rootNode; - } - - @Override - public Object call(Object... args) { - final VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); - FrameInstance oldCurrentFrame = defaultTruffleRuntime().setCurrentFrame(new FrameInstance() { - - public Frame getFrame(FrameAccess access, boolean slowPath) { - return frame; - } - - public boolean isVirtualFrame() { - return false; - } - - public Node getCallNode() { - return null; - } - - public CallTarget getCallTarget() { - return DefaultCallTarget.this; - } - }); - try { - return getRootNode().execute(frame); - } finally { - defaultTruffleRuntime().setCurrentFrame(oldCurrentFrame); - } - } - - private static DefaultTruffleRuntime defaultTruffleRuntime() { - return (DefaultTruffleRuntime) Truffle.getRuntime(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCompilerOptions.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCompilerOptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; - -public class DefaultCompilerOptions implements CompilerOptions { - - public static DefaultCompilerOptions INSTANCE = new DefaultCompilerOptions(); - - public boolean supportsOption(String name) { - return false; - } - - public void setOption(String name, Object value) { - throw new UnsupportedOperationException(String.format("Option %s is not supported by this runtime", name)); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This is runtime specific API. Do not use in a guest language. - */ -public final class DefaultDirectCallNode extends DirectCallNode { - - private boolean inliningForced; - - public DefaultDirectCallNode(CallTarget target) { - super(target); - } - - @Override - public Object call(final VirtualFrame frame, Object[] arguments) { - final CallTarget currentCallTarget = defaultTruffleRuntime().getCurrentFrame().getCallTarget(); - FrameInstance frameInstance = new FrameInstance() { - - public Frame getFrame(FrameAccess access, boolean slowPath) { - return frame; - } - - public boolean isVirtualFrame() { - return false; - } - - public Node getCallNode() { - return DefaultDirectCallNode.this; - } - - public CallTarget getCallTarget() { - return currentCallTarget; - } - }; - defaultTruffleRuntime().pushFrame(frameInstance); - try { - return getCurrentCallTarget().call(arguments); - } finally { - defaultTruffleRuntime().popFrame(); - } - } - - @Override - public void forceInlining() { - inliningForced = true; - } - - @Override - public boolean isInliningForced() { - return inliningForced; - } - - @Override - public CallTarget getClonedCallTarget() { - return null; - } - - @Override - public boolean cloneCallTarget() { - return false; - } - - @Override - public boolean isCallTargetCloningAllowed() { - return false; - } - - @Override - public boolean isInlinable() { - return false; - } - - private static DefaultTruffleRuntime defaultTruffleRuntime() { - return (DefaultTruffleRuntime) Truffle.getRuntime(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultIndirectCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultIndirectCallNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * This is runtime specific API. Do not use in a guest language. - */ -final class DefaultIndirectCallNode extends IndirectCallNode { - @Override - public Object call(final VirtualFrame frame, final CallTarget target, Object[] arguments) { - DefaultTruffleRuntime truffleRuntime = (DefaultTruffleRuntime) Truffle.getRuntime(); - final CallTarget currentCallTarget = truffleRuntime.getCurrentFrame().getCallTarget(); - FrameInstance frameInstance = new FrameInstance() { - public Frame getFrame(FrameAccess access, boolean slowPath) { - return frame; - } - - public boolean isVirtualFrame() { - return false; - } - - public Node getCallNode() { - return DefaultIndirectCallNode.this; - } - - public CallTarget getCallTarget() { - return currentCallTarget; - } - }; - truffleRuntime.pushFrame(frameInstance); - try { - return target.call(arguments); - } finally { - truffleRuntime.popFrame(); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultLoopNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultLoopNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public final class DefaultLoopNode extends LoopNode { - - @Child private RepeatingNode repeatNode; - - public DefaultLoopNode(RepeatingNode repeatNode) { - this.repeatNode = repeatNode; - } - - @Override - public RepeatingNode getRepeatingNode() { - return repeatNode; - } - - @Override - public void executeLoop(VirtualFrame frame) { - while (repeatNode.executeRepeating(frame)) { - // Empty - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; - -/** - * This is an implementation-specific class. Do not use or instantiate it. Instead, use - * {@link TruffleRuntime#createMaterializedFrame(Object[])} or {@link Frame#materialize()} to create - * a {@link MaterializedFrame}. - */ -final class DefaultMaterializedFrame implements MaterializedFrame { - - private final DefaultVirtualFrame wrapped; - - DefaultMaterializedFrame(DefaultVirtualFrame wrapped) { - this.wrapped = wrapped; - } - - @Override - public Object[] getArguments() { - return wrapped.getArguments(); - } - - @Override - public Object getObject(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getObject(slot); - } - - @Override - public void setObject(FrameSlot slot, Object value) { - wrapped.setObject(slot, value); - } - - @Override - public byte getByte(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getByte(slot); - } - - @Override - public void setByte(FrameSlot slot, byte value) { - wrapped.setByte(slot, value); - } - - @Override - public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getBoolean(slot); - } - - @Override - public void setBoolean(FrameSlot slot, boolean value) { - wrapped.setBoolean(slot, value); - } - - @Override - public int getInt(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getInt(slot); - } - - @Override - public void setInt(FrameSlot slot, int value) { - wrapped.setInt(slot, value); - } - - @Override - public long getLong(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getLong(slot); - } - - @Override - public void setLong(FrameSlot slot, long value) { - wrapped.setLong(slot, value); - } - - @Override - public float getFloat(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getFloat(slot); - } - - @Override - public void setFloat(FrameSlot slot, float value) { - wrapped.setFloat(slot, value); - } - - @Override - public double getDouble(FrameSlot slot) throws FrameSlotTypeException { - return wrapped.getDouble(slot); - } - - @Override - public void setDouble(FrameSlot slot, double value) { - wrapped.setDouble(slot, value); - } - - @Override - public Object getValue(FrameSlot slot) { - return wrapped.getValue(slot); - } - - @Override - public MaterializedFrame materialize() { - return this; - } - - @Override - public FrameDescriptor getFrameDescriptor() { - return wrapped.getFrameDescriptor(); - } - - @Override - public boolean isObject(FrameSlot slot) { - return wrapped.isObject(slot); - } - - @Override - public boolean isByte(FrameSlot slot) { - return wrapped.isByte(slot); - } - - @Override - public boolean isBoolean(FrameSlot slot) { - return wrapped.isBoolean(slot); - } - - @Override - public boolean isInt(FrameSlot slot) { - return wrapped.isInt(slot); - } - - @Override - public boolean isLong(FrameSlot slot) { - return wrapped.isLong(slot); - } - - @Override - public boolean isFloat(FrameSlot slot) { - return wrapped.isFloat(slot); - } - - @Override - public boolean isDouble(FrameSlot slot) { - return wrapped.isDouble(slot); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.unsafe.*; - -/** - * Default implementation of the Truffle runtime if the virtual machine does not provide a better - * performing alternative. - *

- * This is an implementation-specific class. Do not use or instantiate it. Instead, use - * {@link Truffle#getRuntime()} to retrieve the current {@link TruffleRuntime}. - */ -public final class DefaultTruffleRuntime implements TruffleRuntime { - - private final ThreadLocal> stackTraces = new ThreadLocal<>(); - private final ThreadLocal currentFrames = new ThreadLocal<>(); - private final Map callTargets = Collections.synchronizedMap(new WeakHashMap()); - - public DefaultTruffleRuntime() { - } - - @Override - public String getName() { - return "Default Truffle Runtime"; - } - - @Override - public RootCallTarget createCallTarget(RootNode rootNode) { - DefaultCallTarget target = new DefaultCallTarget(rootNode); - rootNode.setCallTarget(target); - callTargets.put(target, null); - return target; - } - - public DirectCallNode createDirectCallNode(CallTarget target) { - return new DefaultDirectCallNode(target); - } - - public IndirectCallNode createIndirectCallNode() { - return new DefaultIndirectCallNode(); - } - - @Override - public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) { - return new DefaultVirtualFrame(frameDescriptor, arguments); - } - - @Override - public MaterializedFrame createMaterializedFrame(Object[] arguments) { - return createMaterializedFrame(arguments, new FrameDescriptor()); - } - - @Override - public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) { - return new DefaultMaterializedFrame(new DefaultVirtualFrame(frameDescriptor, arguments)); - } - - @Override - public CompilerOptions createCompilerOptions() { - return new DefaultCompilerOptions(); - } - - @Override - public Assumption createAssumption() { - return createAssumption(null); - } - - @Override - public Assumption createAssumption(String name) { - return new DefaultAssumption(name); - } - - private LinkedList getThreadLocalStackTrace() { - LinkedList result = stackTraces.get(); - if (result == null) { - result = new LinkedList<>(); - stackTraces.set(result); - } - return result; - } - - public FrameInstance setCurrentFrame(FrameInstance newValue) { - FrameInstance oldValue = currentFrames.get(); - currentFrames.set(newValue); - return oldValue; - } - - public void pushFrame(FrameInstance frame) { - getThreadLocalStackTrace().addFirst(frame); - } - - public void popFrame() { - getThreadLocalStackTrace().removeFirst(); - } - - @Override - public T iterateFrames(FrameInstanceVisitor visitor) { - T result = null; - for (FrameInstance frameInstance : getThreadLocalStackTrace()) { - result = visitor.visitFrame(frameInstance); - if (result != null) { - return result; - } - } - return result; - } - - @Override - public FrameInstance getCallerFrame() { - return getThreadLocalStackTrace().peekFirst(); - } - - @Override - public Collection getCallTargets() { - return Collections.unmodifiableSet(callTargets.keySet()); - } - - @Override - public FrameInstance getCurrentFrame() { - return currentFrames.get(); - } - - public T getCapability(Class capability) { - if (capability == UnsafeAccessFactory.class) { - return capability.cast(new UnsafeAccessFactoryImpl()); - } - return null; - } - - public void notifyTransferToInterpreter() { - } - - public LoopNode createLoopNode(RepeatingNode repeating) { - if (!(repeating instanceof Node)) { - throw new IllegalArgumentException("Repeating node must be of type Node."); - } - return new DefaultLoopNode(repeating); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; - -/** - * This is an implementation-specific class. Do not use or instantiate it. Instead, use - * {@link TruffleRuntime#createVirtualFrame(Object[], FrameDescriptor)} to create a - * {@link VirtualFrame}. - */ -final class DefaultVirtualFrame implements VirtualFrame { - - private final FrameDescriptor descriptor; - private final Object[] arguments; - private Object[] locals; - private byte[] tags; - - DefaultVirtualFrame(FrameDescriptor descriptor, Object[] arguments) { - this.descriptor = descriptor; - this.arguments = arguments; - this.locals = new Object[descriptor.getSize()]; - Arrays.fill(locals, descriptor.getDefaultValue()); - this.tags = new byte[descriptor.getSize()]; - } - - @Override - public Object[] getArguments() { - return arguments; - } - - @Override - public MaterializedFrame materialize() { - return new DefaultMaterializedFrame(this); - } - - @Override - public Object getObject(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Object); - return locals[slot.getIndex()]; - } - - @Override - public void setObject(FrameSlot slot, Object value) { - verifySet(slot, FrameSlotKind.Object); - locals[slot.getIndex()] = value; - } - - @Override - public byte getByte(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Byte); - return (byte) locals[slot.getIndex()]; - } - - @Override - public void setByte(FrameSlot slot, byte value) { - verifySet(slot, FrameSlotKind.Byte); - locals[slot.getIndex()] = value; - } - - @Override - public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Boolean); - return (boolean) locals[slot.getIndex()]; - } - - @Override - public void setBoolean(FrameSlot slot, boolean value) { - verifySet(slot, FrameSlotKind.Boolean); - locals[slot.getIndex()] = value; - } - - @Override - public int getInt(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Int); - return (int) locals[slot.getIndex()]; - } - - @Override - public void setInt(FrameSlot slot, int value) { - verifySet(slot, FrameSlotKind.Int); - locals[slot.getIndex()] = value; - } - - @Override - public long getLong(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Long); - return (long) locals[slot.getIndex()]; - } - - @Override - public void setLong(FrameSlot slot, long value) { - verifySet(slot, FrameSlotKind.Long); - locals[slot.getIndex()] = value; - } - - @Override - public float getFloat(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Float); - return (float) locals[slot.getIndex()]; - } - - @Override - public void setFloat(FrameSlot slot, float value) { - verifySet(slot, FrameSlotKind.Float); - locals[slot.getIndex()] = value; - } - - @Override - public double getDouble(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, FrameSlotKind.Double); - return (double) locals[slot.getIndex()]; - } - - @Override - public void setDouble(FrameSlot slot, double value) { - verifySet(slot, FrameSlotKind.Double); - locals[slot.getIndex()] = value; - } - - @Override - public FrameDescriptor getFrameDescriptor() { - return this.descriptor; - } - - @Override - public Object getValue(FrameSlot slot) { - int slotIndex = getSlotIndexChecked(slot); - return locals[slotIndex]; - } - - private int getSlotIndexChecked(FrameSlot slot) { - int slotIndex = slot.getIndex(); - if (slotIndex >= tags.length) { - if (!resize()) { - throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot)); - } - } - return slotIndex; - } - - private void verifySet(FrameSlot slot, FrameSlotKind accessKind) { - int slotIndex = getSlotIndexChecked(slot); - tags[slotIndex] = (byte) accessKind.ordinal(); - } - - private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException { - int slotIndex = getSlotIndexChecked(slot); - byte tag = tags[slotIndex]; - if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) { - throw new FrameSlotTypeException(); - } - } - - private boolean resize() { - int oldSize = tags.length; - int newSize = descriptor.getSize(); - if (newSize > oldSize) { - locals = Arrays.copyOf(locals, newSize); - Arrays.fill(locals, oldSize, newSize, descriptor.getDefaultValue()); - tags = Arrays.copyOf(tags, newSize); - return true; - } - return false; - } - - private byte getTag(FrameSlot slot) { - int slotIndex = getSlotIndexChecked(slot); - return tags[slotIndex]; - } - - @Override - public boolean isObject(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Object.ordinal(); - } - - @Override - public boolean isByte(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Byte.ordinal(); - } - - @Override - public boolean isBoolean(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Boolean.ordinal(); - } - - @Override - public boolean isInt(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Int.ordinal(); - } - - @Override - public boolean isLong(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Long.ordinal(); - } - - @Override - public boolean isFloat(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Float.ordinal(); - } - - @Override - public boolean isDouble(FrameSlot slot) { - return getTag(slot) == FrameSlotKind.Double.ordinal(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.io.*; - -/** - * XXX: Temporary class to make unit tests pass without messing with Message implementations and - * associated nodes too much. - */ -public abstract class SymbolInvoker { - protected abstract Object invoke(Object symbol, Object... args) throws IOException; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/UnsafeAccessFactoryImpl.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/UnsafeAccessFactoryImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import sun.misc.*; - -import com.oracle.truffle.api.unsafe.*; - -final class UnsafeAccessFactoryImpl implements UnsafeAccessFactory { - public UnsafeAccess createUnsafeAccess(final Unsafe unsafe) { - return new UnsafeAccessImpl(unsafe); - } - - private static final class UnsafeAccessImpl implements UnsafeAccess { - private final Unsafe unsafe; - - private UnsafeAccessImpl(Unsafe unsafe) { - this.unsafe = unsafe; - } - - @SuppressWarnings("unchecked") - public T uncheckedCast(Object value, Class type, boolean condition, boolean nonNull) { - return (T) value; - } - - public void putShort(Object receiver, long offset, short value, Object locationIdentity) { - unsafe.putShort(receiver, offset, value); - } - - public void putObject(Object receiver, long offset, Object value, Object locationIdentity) { - unsafe.putObject(receiver, offset, value); - } - - public void putLong(Object receiver, long offset, long value, Object locationIdentity) { - unsafe.putLong(receiver, offset, value); - } - - public void putInt(Object receiver, long offset, int value, Object locationIdentity) { - unsafe.putInt(receiver, offset, value); - } - - public void putFloat(Object receiver, long offset, float value, Object locationIdentity) { - unsafe.putFloat(receiver, offset, value); - } - - public void putDouble(Object receiver, long offset, double value, Object locationIdentity) { - unsafe.putDouble(receiver, offset, value); - } - - public void putByte(Object receiver, long offset, byte value, Object locationIdentity) { - unsafe.putByte(receiver, offset, value); - } - - public void putBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { - unsafe.putBoolean(receiver, offset, value); - } - - public short getShort(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getShort(receiver, offset); - } - - public Object getObject(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getObject(receiver, offset); - } - - public long getLong(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getLong(receiver, offset); - } - - public int getInt(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getInt(receiver, offset); - } - - public float getFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getFloat(receiver, offset); - } - - public double getDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getDouble(receiver, offset); - } - - public byte getByte(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getByte(receiver, offset); - } - - public boolean getBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { - return unsafe.getBoolean(receiver, offset); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Access to AST-based debugging support, which is could be language implementation specific in the - * details chosen to be presented. - *

- * WARNING: this interface is under development and will change substantially. - */ -public interface ASTPrinter { - - /** - * Prints a textual AST display, one line per node, with nesting. - * - * @param p - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - String printTreeToString(Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - */ - String printTreeToString(Node node, int maxDepth); - - /** - * Creates a textual display describing a single (non-wrapper) node, including instrumentation - * status: if Probed, and any tags. - */ - String printNodeWithInstrumentation(Node node); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Enables instrumentation by attaching {@linkplain Probe Probes} to some nodes in a (newly created, - * not yet executed) AST. - * - * @see Probe - * @see Probe#addProbeListener(ProbeListener) - */ -public interface ASTProber { - - /** - * Walk the AST starting at a node and enable instrumentation at selected nodes by attaching - * {@linkplain Probe Probes} to them. Ignore {@linkplain Node#isInstrumentable() - * non-instrumentable} nodes. - */ - void probeAST(Node node); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Listener for receiving the result a client-provided {@linkplain AdvancedInstrumentRoot AST - * fragment}, when executed by a - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @see Instrument - * @see AdvancedInstrumentRoot - * @see AdvancedInstrumentRootFactory - */ -public interface AdvancedInstrumentResultListener { - - /** - * Notifies listener that a client-provided {@linkplain AdvancedInstrumentRoot AST fragment} has - * been executed by an - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument} with the specified result, possibly {@code null}. - *

- * Note: Truffle will attempt to optimize implementations through partial - * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. - * - * @param node the guest-language AST node to which the host Instrument's {@link Probe} is - * attached - * @param vFrame execution frame at the guest-language AST node - * @param result the result of this AST fragment's execution - */ - void notifyResult(Node node, VirtualFrame vFrame, Object result); - - /** - * Notifies listener that execution of client-provided {@linkplain AdvancedInstrumentRoot AST - * fragment} filed during execution by a @linkplain - * Instrument#create(AdvancedInstrumentRootFactory, String) Advanced Instrument}. - *

- * Note: Truffle will attempt to optimize implementations through partial - * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. - * - * @param node the guest-language AST node to which the host Instrument's {@link Probe} is - * attached - * @param vFrame execution frame at the guest-language AST node - * @param ex the exception - */ - void notifyFailure(Node node, VirtualFrame vFrame, RuntimeException ex); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRoot.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRoot.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Root of a client-provided AST fragment that can be executed efficiently, subject to full Truffle - * optimization, by an - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @see Instrument - * @see AdvancedInstrumentRootFactory - * @see AdvancedInstrumentResultListener - */ -public abstract class AdvancedInstrumentRoot extends Node implements InstrumentationNode { - - /** - * Executes this AST fragment on behalf of a client {@link Instrument}, just before the - * guest-language AST node to which the {@link Probe} holding the Instrument is executed. - * - * @param node the guest-language AST node to which the host Instrument's Probe is attached - * @param vFrame execution frame at the guest-language AST node - * @return the result of this AST fragment's execution - */ - public abstract Object executeRoot(Node node, VirtualFrame vFrame); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Creator of {@linkplain AdvancedInstrumentRoot AST fragments} suitable for efficient execution, - * subject to full Truffle optimization, by an - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @see Instrument - * @see AdvancedInstrumentRoot - */ -public interface AdvancedInstrumentRootFactory { - - /** - * Provider of {@linkplain AdvancedInstrumentRoot AST fragment} instances to be executed by the - * Instrumentation Framework at a {@linkplain Probe Probed} site in a guest-language AST. - *

- * Notes: - *

    - *
  • Once the factory has produced an AST fragment at a particular {@linkplain Node AST Node}, - * it will not be called again at that Node.
  • - *
  • In some use cases, for example to implement a breakpoint at a specific program location, - * the Probe argument will be the same for every call. Each Node argument will represent the - * same program location associated with the Probe, but in different clones of the AST.
  • - *
  • In other use cases, for example to implement a breakpoint at any Node with a particular - * {@linkplain SyntaxTag tag}, both the Probe and Node argument may differ. Implementations that - * are sensitive to the lexical context in which the AST fragment will be evaluated must take - * care to build a new, possibly different AST fragment for each request.
  • - *
- * - * @param probe the Probe to which the Instrument requesting the AST fragment is attached - * @param node the guest-language AST location that is the context in which the requesting - * Instrument must execute the AST fragment. - * @return a newly created AST fragment suitable for execution, via instrumentation, in the - * execution context of the specified guest-language AST site. - */ - AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,636 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -// TODO (mlvdv) these statics should not be global. Move them to some kind of context. -// TODO (mlvdv) migrate factory (together with Probe)? break out nested classes? - -/** - * A binding between: - *
    - *
  1. A {@link Probe}: a source of execution events taking place at a program location in - * an executing Truffle AST, and
  2. - *
  3. A listener: a consumer of execution events on behalf of an external client. - *
- *

- * Client-oriented documentation for the use of Instruments is available online at https://wiki.openjdk.java.net/display/Graal/Listening+for+Execution+Events - *

- * The implementation of Instruments is complicated by the requirement that Truffle be able to clone - * ASTs at any time. In particular, any instrumentation-supporting Nodes that have been attached to - * an AST must be cloned along with the AST: AST clones are not permitted to share Nodes. - *

- * AST cloning is intended to be as transparent as possible to clients. This is encouraged - * by providing the {@link SimpleInstrumentListener} for clients that need know nothing more than - * the properties associated with a Probe: it's {@link SourceSection} and any associated instances - * of {@link SyntaxTag}. - *

- * AST cloning is not transparent to clients that use the - * {@link StandardInstrumentListener}, since those event methods identify the concrete Node instance - * (and thus the AST instance) where the event takes place. - *

- *

Implementation Notes: the Life Cycle of an {@link Instrument} at a {@link Probe}

- *

- *

    - *
  • A new Instrument is created in permanent association with a client-provided - * listener.
  • - * - *
  • Multiple Instruments may share a single listener.
  • - * - *
  • An Instrument does nothing until it is {@linkplain Probe#attach(Instrument) attached} to a - * Probe, at which time the Instrument begins routing execution events from the Probe's AST location - * to the Instrument's listener.
  • - * - *
  • Neither Instruments nor Probes are {@link Node}s.
  • - * - *
  • A Probe has a single source-based location in an AST, but manages a separate - * instrumentation chain of Nodes at the equivalent location in each clone of the AST.
  • - *
  • When a probed AST is cloned, the instrumentation chain associated with each Probe is cloned - * along with the rest of the AST.
  • - * - *
  • When a new Instrument (for example an instance of {@link SimpleInstrument} is attached to a - * Probe, the Instrument inserts a new instance of its private Node type, - * {@link SimpleInstrument.SimpleInstrumentNode}, into each of the instrument chains - * managed by the Probe, i.e. one node instance per existing clone of the AST.
  • - * - *
  • If an Instrument is attached to a Probe in an AST that subsequently gets cloned, then the - * Instrument's private Node type will be cloned along with the rest of the the AST.
  • - *
  • Each Instrument's private Node type is a dynamic inner class whose only state is in the - * shared (outer) Instrument instance; that state includes a reference to the Instrument's listener. - *
  • - * - *
  • When an Instrument that has been attached to a Probe is {@linkplain #dispose() disposed}, the - * Instrument searches every instrument chain associated with the Probe and removes the instance of - * its private Node type.
  • - * - *
  • Attaching and disposing an Instrument at a Probe deoptimizes any compilations of the - * AST.
  • - * - *
- * - * @see Probe - * @see TruffleEvents - */ -public abstract class Instrument { - - /** - * Creates a Simple Instrument: this Instrument routes execution events to a - * client-provided listener. - * - * @param listener a listener for execution events - * @param instrumentInfo optional description of the instrument's role, intended for debugging. - * @return a new instrument, ready for attachment at a probe - */ - public static Instrument create(SimpleInstrumentListener listener, String instrumentInfo) { - return new SimpleInstrument(listener, instrumentInfo); - } - - /** - * Creates a Standard Instrument: this Instrument routes execution events, together - * with access to Truffle execution state, to a client-provided listener. - * - * @param standardListener a listener for execution events and execution state - * @param instrumentInfo optional description of the instrument's role, intended for debugging. - * @return a new instrument, ready for attachment at a probe - */ - public static Instrument create(StandardInstrumentListener standardListener, String instrumentInfo) { - return new StandardInstrument(standardListener, instrumentInfo); - } - - /** - * Creates an Advanced Instrument: this Instrument executes efficiently, subject to - * full Truffle optimization, a client-provided AST fragment every time the Probed node is - * entered. - *

- * Any {@link RuntimeException} thrown by execution of the fragment is caught by the framework - * and reported to the listener; there is no other notification. - * - * @param resultListener optional client callback for results/failure notification - * @param rootFactory provider of AST fragments on behalf of the client - * @param requiredResultType optional requirement, any non-assignable result is reported to the - * the listener, if any, as a failure - * @param instrumentInfo optional description of the instrument's role, intended for debugging. - * @return a new instrument, ready for attachment at a probe - */ - public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { - return new AdvancedInstrument(resultListener, rootFactory, requiredResultType, instrumentInfo); - } - - // TODO (mlvdv) experimental - /** - * For implementation testing. - */ - public static Instrument create(TruffleOptListener listener) { - return new TruffleOptInstrument(listener, null); - } - - /** - * Has this instrument been disposed? stays true once set. - */ - private boolean isDisposed = false; - - protected Probe probe = null; - - /** - * Optional documentation, mainly for debugging. - */ - private final String instrumentInfo; - - private Instrument(String instrumentInfo) { - this.instrumentInfo = instrumentInfo; - } - - /** - * Gets the {@link Probe} to which this Instrument is currently attached: {@code null} if not - * yet attached to a Probe or if this Instrument has been {@linkplain #dispose() disposed}. - */ - public Probe getProbe() { - return probe; - } - - /** - * Removes this Instrument from the Probe to which it attached and renders this Instrument - * inert. - * - * @throws IllegalStateException if this instrument has already been disposed - */ - public void dispose() throws IllegalStateException { - if (isDisposed) { - throw new IllegalStateException("Attempt to dispose an already disposed Instrumennt"); - } - if (probe != null) { - // It's attached - probe.disposeInstrument(this); - probe = null; - } - this.isDisposed = true; - } - - /** - * For internal implementation only. - */ - void setAttachedTo(Probe probe) { - this.probe = probe; - } - - /** - * Has this instrument been disposed and rendered unusable? - */ - boolean isDisposed() { - return isDisposed; - } - - abstract AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode); - - /** - * Removes this instrument from an instrument chain. - */ - abstract AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode); - - /** - * An instrument that propagates events to an instance of {@link SimpleInstrumentListener}. - */ - private static final class SimpleInstrument extends Instrument { - - /** - * Tool-supplied listener for events. - */ - private final SimpleInstrumentListener simpleListener; - - private SimpleInstrument(SimpleInstrumentListener simpleListener, String instrumentInfo) { - super(instrumentInfo); - this.simpleListener = simpleListener; - } - - @Override - AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { - return new SimpleInstrumentNode(nextNode); - } - - @Override - AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { - boolean found = false; - if (instrumentNode != null) { - if (instrumentNode.getInstrument() == this) { - // Found the match at the head of the chain - return instrumentNode.nextInstrumentNode; - } - // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(SimpleInstrument.this); - } - if (!found) { - throw new IllegalStateException("Couldn't find instrument node to remove: " + this); - } - return instrumentNode; - } - - /** - * Node that implements a {@link SimpleInstrument} in a particular AST. - */ - @NodeInfo(cost = NodeCost.NONE) - private final class SimpleInstrumentNode extends AbstractInstrumentNode { - - private SimpleInstrumentNode(AbstractInstrumentNode nextNode) { - super(nextNode); - } - - public void enter(Node node, VirtualFrame vFrame) { - SimpleInstrument.this.simpleListener.enter(SimpleInstrument.this.probe); - if (nextInstrumentNode != null) { - nextInstrumentNode.enter(node, vFrame); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - SimpleInstrument.this.simpleListener.returnVoid(SimpleInstrument.this.probe); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnVoid(node, vFrame); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - SimpleInstrument.this.simpleListener.returnValue(SimpleInstrument.this.probe, result); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnValue(node, vFrame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - SimpleInstrument.this.simpleListener.returnExceptional(SimpleInstrument.this.probe, exception); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnExceptional(node, vFrame, exception); - } - } - - public String instrumentationInfo() { - final String info = getInstrumentInfo(); - return info != null ? info : simpleListener.getClass().getSimpleName(); - } - } - } - - /** - * An instrument that propagates events to an instance of {@link StandardInstrumentListener}. - */ - private static final class StandardInstrument extends Instrument { - - /** - * Tool-supplied listener for AST events. - */ - private final StandardInstrumentListener standardListener; - - private StandardInstrument(StandardInstrumentListener standardListener, String instrumentInfo) { - super(instrumentInfo); - this.standardListener = standardListener; - } - - @Override - AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { - return new StandardInstrumentNode(nextNode); - } - - @Override - AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { - boolean found = false; - if (instrumentNode != null) { - if (instrumentNode.getInstrument() == this) { - // Found the match at the head of the chain - return instrumentNode.nextInstrumentNode; - } - // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(StandardInstrument.this); - } - if (!found) { - throw new IllegalStateException("Couldn't find instrument node to remove: " + this); - } - return instrumentNode; - } - - /** - * Node that implements a {@link StandardInstrument} in a particular AST. - */ - @NodeInfo(cost = NodeCost.NONE) - private final class StandardInstrumentNode extends AbstractInstrumentNode { - - private StandardInstrumentNode(AbstractInstrumentNode nextNode) { - super(nextNode); - } - - public void enter(Node node, VirtualFrame vFrame) { - standardListener.enter(StandardInstrument.this.probe, node, vFrame); - if (nextInstrumentNode != null) { - nextInstrumentNode.enter(node, vFrame); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - standardListener.returnVoid(StandardInstrument.this.probe, node, vFrame); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnVoid(node, vFrame); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - standardListener.returnValue(StandardInstrument.this.probe, node, vFrame, result); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnValue(node, vFrame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - standardListener.returnExceptional(StandardInstrument.this.probe, node, vFrame, exception); - if (nextInstrumentNode != null) { - nextInstrumentNode.returnExceptional(node, vFrame, exception); - } - } - - public String instrumentationInfo() { - final String info = getInstrumentInfo(); - return info != null ? info : standardListener.getClass().getSimpleName(); - } - } - } - - /** - * An instrument that allows clients to provide an AST fragment to be executed directly from - * within a Probe's instrumentation chain, and thus directly in the executing Truffle - * AST with potential for full optimization. - */ - private static final class AdvancedInstrument extends Instrument { - - private final AdvancedInstrumentResultListener resultListener; - private final AdvancedInstrumentRootFactory rootFactory; - private final Class requiredResultType; - - private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { - super(instrumentInfo); - this.resultListener = resultListener; - this.rootFactory = rootFactory; - this.requiredResultType = requiredResultType; - } - - @Override - AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { - return new AdvancedInstrumentNode(nextNode); - } - - @Override - AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { - boolean found = false; - if (instrumentNode != null) { - if (instrumentNode.getInstrument() == this) { - // Found the match at the head of the chain - return instrumentNode.nextInstrumentNode; - } - // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(AdvancedInstrument.this); - } - if (!found) { - throw new IllegalStateException("Couldn't find instrument node to remove: " + this); - } - return instrumentNode; - } - - /** - * Node that implements a {@link AdvancedInstrument} in a particular AST. - */ - @NodeInfo(cost = NodeCost.NONE) - private final class AdvancedInstrumentNode extends AbstractInstrumentNode { - - @Child private AdvancedInstrumentRoot instrumentRoot; - - private AdvancedInstrumentNode(AbstractInstrumentNode nextNode) { - super(nextNode); - } - - public void enter(Node node, VirtualFrame vFrame) { - if (instrumentRoot == null) { - try { - final AdvancedInstrumentRoot newInstrumentRoot = AdvancedInstrument.this.rootFactory.createInstrumentRoot(AdvancedInstrument.this.probe, node); - if (newInstrumentRoot != null) { - instrumentRoot = newInstrumentRoot; - adoptChildren(); - AdvancedInstrument.this.probe.invalidateProbeUnchanged(); - } - } catch (RuntimeException ex) { - if (resultListener != null) { - resultListener.notifyFailure(node, vFrame, ex); - } - } - } - if (instrumentRoot != null) { - try { - final Object result = instrumentRoot.executeRoot(node, vFrame); - if (resultListener != null) { - checkResultType(result); - resultListener.notifyResult(node, vFrame, result); - } - } catch (RuntimeException ex) { - if (resultListener != null) { - resultListener.notifyFailure(node, vFrame, ex); - } - } - } - if (nextInstrumentNode != null) { - nextInstrumentNode.enter(node, vFrame); - } - } - - private void checkResultType(Object result) { - if (requiredResultType == null) { - return; - } - if (result == null) { - throw new RuntimeException("Instrument result null: " + requiredResultType.getSimpleName() + " is required"); - } - if (!(requiredResultType.isAssignableFrom(result.getClass()))) { - throw new RuntimeException("Instrument result " + result.toString() + " not assignable to " + requiredResultType.getSimpleName()); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnVoid(node, vFrame); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnValue(node, vFrame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnExceptional(node, vFrame, exception); - } - } - - public String instrumentationInfo() { - final String info = getInstrumentInfo(); - return info != null ? info : rootFactory.getClass().getSimpleName(); - } - } - } - - public interface TruffleOptListener { - void notifyIsCompiled(boolean isCompiled); - } - - private static final class TruffleOptInstrument extends Instrument { - - private final TruffleOptListener toolOptListener; - - private TruffleOptInstrument(TruffleOptListener listener, String instrumentInfo) { - super(instrumentInfo); - this.toolOptListener = listener; - } - - @Override - AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { - return new TruffleOptInstrumentNode(nextNode); - } - - @Override - AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { - boolean found = false; - if (instrumentNode != null) { - if (instrumentNode.getInstrument() == this) { - // Found the match at the head of the chain - return instrumentNode.nextInstrumentNode; - } - // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(TruffleOptInstrument.this); - } - if (!found) { - throw new IllegalStateException("Couldn't find instrument node to remove: " + this); - } - return instrumentNode; - } - - @NodeInfo(cost = NodeCost.NONE) - private final class TruffleOptInstrumentNode extends AbstractInstrumentNode { - - private boolean isCompiled; - - private TruffleOptInstrumentNode(AbstractInstrumentNode nextNode) { - super(nextNode); - this.isCompiled = CompilerDirectives.inCompiledCode(); - } - - public void enter(Node node, VirtualFrame vFrame) { - if (this.isCompiled != CompilerDirectives.inCompiledCode()) { - this.isCompiled = CompilerDirectives.inCompiledCode(); - TruffleOptInstrument.this.toolOptListener.notifyIsCompiled(this.isCompiled); - } - if (nextInstrumentNode != null) { - nextInstrumentNode.enter(node, vFrame); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnVoid(node, vFrame); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnValue(node, vFrame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - if (nextInstrumentNode != null) { - nextInstrumentNode.returnExceptional(node, vFrame, exception); - } - } - - public String instrumentationInfo() { - final String info = getInstrumentInfo(); - return info != null ? info : toolOptListener.getClass().getSimpleName(); - } - } - } - - @NodeInfo(cost = NodeCost.NONE) - abstract class AbstractInstrumentNode extends Node implements TruffleEvents, InstrumentationNode { - - @Child protected AbstractInstrumentNode nextInstrumentNode; - - protected AbstractInstrumentNode(AbstractInstrumentNode nextNode) { - this.nextInstrumentNode = nextNode; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - /** - * Gets the instrument that created this node. - */ - private Instrument getInstrument() { - return Instrument.this; - } - - /** - * Removes the node from this chain that was added by a particular instrument, assuming that - * the head of the chain is not the one to be replaced. This is awkward, but is required - * because {@link Node#replace(Node)} won't take a {@code null} argument. This doesn't work - * for the tail of the list, which would be replacing itself with null. So the replacement - * must be directed the parent of the node being removed. - */ - private boolean removeFromChain(Instrument instrument) { - assert getInstrument() != instrument; - if (nextInstrumentNode == null) { - return false; - } - if (nextInstrumentNode.getInstrument() == instrument) { - // Next is the one to remove - if (nextInstrumentNode.nextInstrumentNode == null) { - // Next is at the tail; just forget - nextInstrumentNode = null; - } else { - // Replace next with its successor - nextInstrumentNode.replace(nextInstrumentNode.nextInstrumentNode); - } - return true; - } - return nextInstrumentNode.removeFromChain(instrument); - } - - protected String getInstrumentInfo() { - return Instrument.this.instrumentInfo; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -public class InstrumentationException extends Exception { - - public InstrumentationException(RuntimeException ex) { - super(ex); - } - - private static final long serialVersionUID = 447857066220935502L; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A marker interface for Truffle {@linkplain Node nodes} that internally implement the - * Instrumentation Framework. Such nodes should not be part of any Guest Language execution - * semantics, and should in general not be visible to ordinary Instrumentation clients. - */ -public interface InstrumentationNode { - - /** - * A short description of the particular role played by the node, intended to support debugging. - */ - String instrumentationInfo(); - - /** - * Events that propagate through the {@linkplain InstrumentationNode implementation nodes} of - * the Instrumentation Framework, not visible in this form to Instrumentation clients. - */ - interface TruffleEvents { - - /** - * An AST node's execute method is about to be called. - */ - void enter(Node node, VirtualFrame vFrame); - - /** - * An AST Node's {@code void}-valued execute method has just returned. - */ - void returnVoid(Node node, VirtualFrame vFrame); - - /** - * An AST Node's execute method has just returned a value (boxed if primitive). - */ - void returnValue(Node node, VirtualFrame vFrame, Object result); - - /** - * An AST Node's execute method has just thrown an exception. - */ - void returnExceptional(Node node, VirtualFrame vFrame, Exception exception); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationTool.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationTool.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * {@linkplain Instrument Instrumentation}-based tools that gather data during Guest Language - * program execution. - *

- * Tools share a common life cycle: - *

    - *
  • A newly created tool is inert until {@linkplain #install() installed}.
  • - *
  • An installed tool becomes enabled and immediately begins installing - * {@linkplain Instrument instrumentation} on subsequently created ASTs and collecting data from - * those instruments
  • - *
  • A tool may only be installed once.
  • - *
  • It should be possible to install multiple instances of a tool, possibly (but not necessarily) - * configured differently with respect to what data is being collected.
  • - *
  • Once installed, a tool can be {@linkplain #setEnabled(boolean) enabled and disabled} - * arbitrarily.
  • - *
  • A disabled tool: - *
      - *
    • Collects no data;
    • - *
    • Retains existing AST instrumentation;
    • - *
    • Continues to instrument newly created ASTs; and
    • - *
    • Retains previously collected data.
    • - *
    - *
  • - *
  • An installed tool may be {@linkplain #reset() reset} at any time, which leaves the tool - * installed but with all previously collected data removed.
  • - *
  • A {@linkplain #dispose() disposed} tool removes all instrumentation (but not - * {@linkplain Probe probes}) and becomes permanently disabled; previously collected data persists.
  • - *
- *

- * Tool-specific methods that access data collected by the tool should: - *

    - *
  • Return modification-safe representations of the data; and
  • - *
  • Not change the state of the data.
  • - *
- * Note:
- * Tool installation is currently global to the Truffle Execution environment. When - * language-agnostic management of individual execution environments is added to the platform, - * installation will be (optionally) specific to a single execution environment. - */ -public abstract class InstrumentationTool { - // TODO (mlvdv) still thinking about the most appropriate name for this class of tools - - private enum ToolState { - - /** Not yet installed, inert. */ - UNINSTALLED, - - /** Installed, collecting data. */ - ENABLED, - - /** Installed, not collecting data. */ - DISABLED, - - /** Was installed, but now removed, inactive, and no longer usable. */ - DISPOSED; - } - - private ToolState toolState = ToolState.UNINSTALLED; - - protected InstrumentationTool() { - } - - /** - * Connect the tool to some part of the Truffle runtime, and enable data collection to start. - * Instrumentation will only be added to subsequently created ASTs. - * - * @throws IllegalStateException if the tool has previously been installed. - */ - public final void install() { - checkUninstalled(); - if (internalInstall()) { - toolState = ToolState.ENABLED; - } - } - - /** - * @return whether the tool is currently collecting data. - */ - public final boolean isEnabled() { - return toolState == ToolState.ENABLED; - } - - /** - * Switches tool state between enabled (collecting data) and disabled (not - * collecting data, but keeping data already collected). - * - * @throws IllegalStateException if not yet installed or disposed. - */ - public final void setEnabled(boolean isEnabled) { - checkInstalled(); - internalSetEnabled(isEnabled); - toolState = isEnabled ? ToolState.ENABLED : ToolState.DISABLED; - } - - /** - * Clears any data already collected, but otherwise does not change the state of the tool. - * - * @throws IllegalStateException if not yet installed or disposed. - */ - public final void reset() { - checkInstalled(); - internalReset(); - } - - /** - * Makes the tool permanently disabled, removes instrumentation, but keeps data already - * collected. - * - * @throws IllegalStateException if not yet installed or disposed. - */ - public final void dispose() { - checkInstalled(); - internalDispose(); - toolState = ToolState.DISPOSED; - } - - /** - * @return whether the installation succeeded. - */ - protected abstract boolean internalInstall(); - - /** - * No subclass action required. - * - * @param isEnabled - */ - protected void internalSetEnabled(boolean isEnabled) { - } - - protected abstract void internalReset(); - - protected abstract void internalDispose(); - - /** - * Ensure that the tool is currently installed. - * - * @throws IllegalStateException - */ - private void checkInstalled() throws IllegalStateException { - if (toolState == ToolState.UNINSTALLED) { - throw new IllegalStateException("Tool " + getClass().getSimpleName() + " not yet installed"); - } - if (toolState == ToolState.DISPOSED) { - throw new IllegalStateException("Tool " + getClass().getSimpleName() + " has been disposed"); - } - } - - /** - * Ensure that the tool has not yet been installed. - * - * @throws IllegalStateException - */ - private void checkUninstalled() { - if (toolState != ToolState.UNINSTALLED) { - throw new IllegalStateException("Tool " + getClass().getSimpleName() + " has already been installed"); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Controls breaking out of an execution context, such as a shell or eval. - */ -public final class KillException extends ControlFlowException { - - private static final long serialVersionUID = 3163641880088766957L; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,486 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import java.lang.ref.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; - -//TODO (mlvdv) these statics should not be global. Move them to some kind of context. - -/** - * A binding between: - *
    - *
  1. A program location in an executing Truffle AST (corresponding to a {@link SourceSection}), - * and
  2. - *
  3. A dynamically managed collection of "attached" {@linkplain Instrument Instruments} that - * receive event notifications on behalf of external clients.
  4. - *
- *

- * Client-oriented documentation for the use of Probes is available online at https://wiki.openjdk.java.net/display/Graal/Finding+Probes - *

- *

Implementation notes:

- *

- *

    - *
  • A Probe must be permanently associated with a program location, defined by a - * particular {@link SourceSection}, even though: - *
      - *
    • that location is represented in an AST as a {@link Node}, which might be replaced through - * optimizations such as specialization, and
    • - *
    • Truffle may clone the AST so that the location is actually represented by multiple - * Nodes in multiple ASTs.
    • - *
    - *
  • - * - *
  • The effect of the binding is to intercept {@linkplain TruffleEvents execution events} - * arriving at the "probed" AST Node and notify each attached {@link Instrument} before execution is - * allowed to proceed to the child and again after execution completes.
  • - * - *
  • The method {@link Node#probe()} creates a Probe on an AST Node; redundant calls return the - * same Probe.
  • - * - *
  • The "probing" of a Truffle AST must be done after the AST is complete (i.e. parent pointers - * correctly assigned), but before any cloning or executions. This is done by creating an instance - * of {@link ASTProber} and registering it via {@link #registerASTProber(ASTProber)}. Once - * registered, it will be applied automatically to every newly created AST.
  • - * - *
  • The "probing" of an AST Node is implemented by insertion of a {@link ProbeNode.WrapperNode} - * into the AST (as new parent of the Node being probed), together with an associated - * {@link ProbeNode} that routes execution events at the probed Node to all the - * {@linkplain Instrument Instruments} attached to the Probe's instrument chain.
  • - * - *
  • When Truffle clones an AST, any attached WrapperNodes and ProbeNodes are cloned as well, - * together with their attached instrument chains. Each Probe instance intercepts cloning events and - * keeps track of all AST copies.
  • - * - *
  • All attached {@link InstrumentationNode}s effectively become part of the running program: - *
      - *
    • Good News: instrumentation code implicitly benefits from every kind of Truffle optimization.
    • - *
    • Bad News: instrumentation code must be implemented carefully to avoid interfering with any - * Truffle optimizations.
    • - *
    - *
  • - * - *
- * - * @see Instrument - * @see ASTProber - * @see ProbeListener - * @see SyntaxTag - */ -public final class Probe { - - private static final boolean TRACE = false; - private static final String TRACE_PREFIX = "PROBE: "; - private static final PrintStream OUT = System.out; - - private static void trace(String format, Object... args) { - if (TRACE) { - OUT.println(TRACE_PREFIX + String.format(format, args)); - } - } - - private static final List astProbers = new ArrayList<>(); - - private static final List probeListeners = new ArrayList<>(); - - /** - * All Probes that have been created. - */ - private static final List> probes = new ArrayList<>(); - - /** - * A global trap that triggers notification just before executing any Node that is Probed with a - * matching tag. - */ - @CompilationFinal private static SyntaxTagTrap beforeTagTrap = null; - - /** - * A global trap that triggers notification just after executing any Node that is Probed with a - * matching tag. - */ - @CompilationFinal private static SyntaxTagTrap afterTagTrap = null; - - private static final class FindSourceVisitor implements NodeVisitor { - - Source source = null; - - public boolean visit(Node node) { - final SourceSection sourceSection = node.getSourceSection(); - if (sourceSection != null) { - source = sourceSection.getSource(); - return false; - } - return true; - } - } - - /** - * Walks an AST, looking for the first node with an assigned {@link SourceSection} and returning - * the {@link Source}. - */ - private static Source findSource(Node node) { - final FindSourceVisitor visitor = new FindSourceVisitor(); - node.accept(visitor); - return visitor.source; - } - - /** - * Enables instrumentation at selected nodes in all subsequently constructed ASTs. - */ - public static void registerASTProber(ASTProber prober) { - astProbers.add(prober); - } - - public static void unregisterASTProber(ASTProber prober) { - astProbers.remove(prober); - } - - /** - * Enables instrumentation in a newly created AST by applying all registered instances of - * {@link ASTProber}. - */ - public static void applyASTProbers(Node node) { - - String name = ""; - final Source source = findSource(node); - if (source != null) { - name = source.getShortName(); - } else { - final SourceSection sourceSection = node.getEncapsulatingSourceSection(); - if (sourceSection != null) { - name = sourceSection.getShortDescription(); - } - } - trace("START %s", name); - for (ProbeListener listener : probeListeners) { - listener.startASTProbing(source); - } - for (ASTProber prober : astProbers) { - prober.probeAST(node); - } - for (ProbeListener listener : probeListeners) { - listener.endASTProbing(source); - } - trace("FINISHED %s", name); - } - - /** - * Adds a {@link ProbeListener} to receive events. - */ - public static void addProbeListener(ProbeListener listener) { - assert listener != null; - probeListeners.add(listener); - } - - /** - * Removes a {@link ProbeListener}. Ignored if listener not found. - */ - public static void removeProbeListener(ProbeListener listener) { - probeListeners.remove(listener); - } - - /** - * Returns all {@link Probe}s holding a particular {@link SyntaxTag}, or the whole collection of - * probes if the specified tag is {@code null}. - * - * @return A collection of probes containing the given tag. - */ - public static Collection findProbesTaggedAs(SyntaxTag tag) { - final List taggedProbes = new ArrayList<>(); - for (WeakReference ref : probes) { - Probe probe = ref.get(); - if (probe != null) { - if (tag == null || probe.isTaggedAs(tag)) { - taggedProbes.add(ref.get()); - } - } - } - return taggedProbes; - } - - // TODO (mlvdv) generalize to permit multiple "before traps" without a performance hit? - /** - * Sets the current "before tag trap"; there can be no more than one in effect. - *
    - *
  • The before-trap triggers a callback just before execution - * reaches any {@link Probe} (either existing or subsequently created) - * with the specified {@link SyntaxTag}.
  • - *
  • Setting the before-trap to {@code null} clears an existing before-trap.
  • - *
  • Setting a non{@code -null} before-trap when one is already set clears the previously set - * before-trap.
  • - *
- * - * @param newBeforeTagTrap The new "before" {@link SyntaxTagTrap} to set. - */ - public static void setBeforeTagTrap(SyntaxTagTrap newBeforeTagTrap) { - beforeTagTrap = newBeforeTagTrap; - for (WeakReference ref : probes) { - final Probe probe = ref.get(); - if (probe != null) { - probe.notifyTrapsChanged(); - } - } - } - - // TODO (mlvdv) generalize to permit multiple "after traps" without a performance hit? - /** - * Sets the current "after tag trap"; there can be no more than one in effect. - *
    - *
  • The after-trap triggers a callback just after execution leaves - * any {@link Probe} (either existing or subsequently created) with - * the specified {@link SyntaxTag}.
  • - *
  • Setting the after-trap to {@code null} clears an existing after-trap.
  • - *
  • Setting a non{@code -null} after-trap when one is already set clears the previously set - * after-trap.
  • - *
- * - * @param newAfterTagTrap The new "after" {@link SyntaxTagTrap} to set. - */ - public static void setAfterTagTrap(SyntaxTagTrap newAfterTagTrap) { - afterTagTrap = newAfterTagTrap; - for (WeakReference ref : probes) { - final Probe probe = ref.get(); - if (probe != null) { - probe.notifyTrapsChanged(); - } - } - } - - private final SourceSection sourceSection; - private final ArrayList tags = new ArrayList<>(); - private final List> probeNodeClones = new ArrayList<>(); - - /* - * Invalidated whenever something changes in the Probe and its Instrument chain, so need deopt - */ - private final CyclicAssumption probeStateUnchangedCyclic = new CyclicAssumption("Probe state unchanged"); - - /* - * The assumption that nothing had changed in this probe, the last time anybody checked (when - * there may have been a deopt). Every time a check fails, gets replaced by a new unchanged - * assumption. - */ - @CompilationFinal private Assumption probeStateUnchangedAssumption = probeStateUnchangedCyclic.getAssumption(); - - // Must invalidate whenever changed - @CompilationFinal private boolean isBeforeTrapActive = false; - - // Must invalidate whenever changed - @CompilationFinal private boolean isAfterTrapActive = false; - - /** - * Intended for use only by {@link ProbeNode}. - */ - Probe(ProbeNode probeNode, SourceSection sourceSection) { - this.sourceSection = sourceSection; - probes.add(new WeakReference<>(this)); - registerProbeNodeClone(probeNode); - if (TRACE) { - final String location = this.sourceSection == null ? "" : sourceSection.getShortDescription(); - trace("ADDED %s %s %s", "Probe@", location, getTagsDescription()); - } - for (ProbeListener listener : probeListeners) { - listener.newProbeInserted(this); - } - } - - /** - * Is this node tagged as belonging to a particular human-sensible category of language - * constructs? - */ - public boolean isTaggedAs(SyntaxTag tag) { - assert tag != null; - return tags.contains(tag); - } - - /** - * In which user-sensible categories has this node been tagged (empty set if none). - */ - public Collection getSyntaxTags() { - return Collections.unmodifiableCollection(tags); - } - - /** - * Adds a {@linkplain SyntaxTag tag} to the set of tags associated with this {@link Probe}; - * {@code no-op} if already in the set. - */ - public void tagAs(SyntaxTag tag, Object tagValue) { - assert tag != null; - if (!tags.contains(tag)) { - tags.add(tag); - for (ProbeListener listener : probeListeners) { - listener.probeTaggedAs(this, tag, tagValue); - } - - // Update the status of this Probe with respect to global tag traps - boolean tagTrapsChanged = false; - if (beforeTagTrap != null && tag == beforeTagTrap.getTag()) { - this.isBeforeTrapActive = true; - tagTrapsChanged = true; - } - if (afterTagTrap != null && tag == afterTagTrap.getTag()) { - this.isAfterTrapActive = true; - tagTrapsChanged = true; - } - if (tagTrapsChanged) { - invalidateProbeUnchanged(); - } - if (TRACE) { - trace("TAGGED as %s: %s", tag, getShortDescription()); - } - } - } - - /** - * Adds instrumentation at this Probe. - * - * @param instrument an instrument not yet attached to a probe - * @throws IllegalStateException if the instrument has ever been attached before - */ - public void attach(Instrument instrument) throws IllegalStateException { - if (instrument.isDisposed()) { - throw new IllegalStateException("Attempt to attach disposed instrument"); - } - if (instrument.getProbe() != null) { - throw new IllegalStateException("Attampt to attach an already attached instrument"); - } - instrument.setAttachedTo(this); - for (WeakReference ref : probeNodeClones) { - final ProbeNode probeNode = ref.get(); - if (probeNode != null) { - probeNode.addInstrument(instrument); - } - } - invalidateProbeUnchanged(); - } - - /** - * Gets the {@link SourceSection} associated with the Guest Language AST node being - * instrumented, possibly {@code null}. - */ - public SourceSection getProbedSourceSection() { - return sourceSection; - } - - public String getShortDescription() { - final String location = sourceSection == null ? "" : sourceSection.getShortDescription(); - return "Probe@" + location + getTagsDescription(); - } - - /** - * Internal method for removing and rendering inert a specific instrument previously attached at - * this Probe. - * - * @param instrument an instrument already attached - * @throws IllegalStateException if instrument not attached at this Probe - * @see Instrument#dispose() - */ - void disposeInstrument(Instrument instrument) throws IllegalStateException { - for (WeakReference ref : probeNodeClones) { - final ProbeNode probeNode = ref.get(); - if (probeNode != null) { - probeNode.removeInstrument(instrument); - } - } - invalidateProbeUnchanged(); - } - - /** - * Receives notification that a new clone of the instrument chain associated with this - * {@link Probe} has been created as a side-effect of AST cloning. - */ - void registerProbeNodeClone(ProbeNode probeNode) { - probeNodeClones.add(new WeakReference<>(probeNode)); - } - - /** - * Gets the currently active before {@linkplain SyntaxTagTrap Tag - * Trap} at this Probe. Non{@code -null} if the global - * {@linkplain Probe#setBeforeTagTrap(SyntaxTagTrap) Before Tag Trap} is set and if this Probe - * holds the {@link SyntaxTag} specified in the trap. - */ - SyntaxTagTrap getBeforeTrap() { - checkProbeUnchanged(); - return isBeforeTrapActive ? beforeTagTrap : null; - } - - /** - * Gets the currently active after {@linkplain SyntaxTagTrap Tag Trap} - * at this Probe. Non{@code -null} if the global - * {@linkplain Probe#setAfterTagTrap(SyntaxTagTrap) After Tag Trap} is set and if this Probe - * holds the {@link SyntaxTag} specified in the trap. - */ - SyntaxTagTrap getAfterTrap() { - checkProbeUnchanged(); - return isAfterTrapActive ? afterTagTrap : null; - } - - /** - * To be called wherever in the Probe/Instrument chain there are dependencies on the probe - * state's @CompilatonFinal fields. - */ - void checkProbeUnchanged() { - try { - probeStateUnchangedAssumption.check(); - } catch (InvalidAssumptionException ex) { - // Failure creates an implicit deoptimization - // Get the assumption associated with the new probe state - this.probeStateUnchangedAssumption = probeStateUnchangedCyclic.getAssumption(); - } - } - - void invalidateProbeUnchanged() { - probeStateUnchangedCyclic.invalidate(); - } - - private void notifyTrapsChanged() { - this.isBeforeTrapActive = beforeTagTrap != null && this.isTaggedAs(beforeTagTrap.getTag()); - this.isAfterTrapActive = afterTagTrap != null && this.isTaggedAs(afterTagTrap.getTag()); - invalidateProbeUnchanged(); - } - - private String getTagsDescription() { - final StringBuilder sb = new StringBuilder(); - sb.append("["); - String prefix = ""; - for (SyntaxTag tag : tags) { - sb.append(prefix); - prefix = ","; - sb.append(tag.toString()); - } - sb.append("]"); - return sb.toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.instrument.ProbeFailure.Reason; -import com.oracle.truffle.api.nodes.*; - -/** - * An exception thrown when {@link Node#probe()} fails because of an implementation failure. - *

- * Language and tool implementations should ensure that clients of tools never see this exception. - */ -public class ProbeException extends RuntimeException { - static final long serialVersionUID = 1L; - private final ProbeFailure failure; - - public ProbeException(Reason reason, Node parent, Node child, Object wrapper) { - this.failure = new ProbeFailure(reason, parent, child, wrapper); - } - - public ProbeFailure getFailure() { - return failure; - } - - @Override - public String toString() { - return failure.getMessage(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java Wed Jun 17 10:01:47 2015 +0200 +++ /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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; - -/** - * Description of a failed attempt to instrument an AST node. - */ -public final class ProbeFailure { - - public enum Reason { - - /** - * Node to be probed has no parent. - */ - NO_PARENT("Node to be probed has no parent"), - - /** - * The node to be probed is a wrapper. - */ - WRAPPER_NODE("The node to be probed is a wrapper"), - - /** - * The node to be probed returned {@link Node#isInstrumentable()}{@code == false}. - */ - NOT_INSTRUMENTABLE("The node to be project is \"not instrumentable\""), - - /** - * No wrapper could be created that is also a {@link Node}. - */ - NO_WRAPPER("No wrapper could be created"), - - /** - * Wrapper not assignable to the parent's child field. - */ - WRAPPER_TYPE("Wrapper not assignable to parent's child field"); - - final String message; - - private Reason(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - } - - private final Reason reason; - private final Node parent; - private final Node child; - private final Object wrapper; - - /** - * Description of an internal failure of {@link Node#probe()}. - * - * @param reason what caused the failure - * @param parent the parent, if known, of the child being probed - * @param child this child being probed - * @param wrapper the {@link WrapperNode} created to implement the probe - */ - public ProbeFailure(Reason reason, Node parent, Node child, Object wrapper) { - this.reason = reason; - this.parent = parent; - this.child = child; - this.wrapper = wrapper; - } - - /** - * @return a short explanation of the failure - */ - public Reason getReason() { - return reason; - } - - /** - * @return the parent, if any, of the node being probed - */ - public Node getParent() { - return parent; - } - - /** - * @return the node being probed - */ - public Node getChild() { - return child; - } - - /** - * @return the {@link WrapperNode} created for the probe attempt - */ - public Object getWrapper() { - return wrapper; - } - - public String getMessage() { - final StringBuilder sb = new StringBuilder(reason.message + ": "); - if (parent != null) { - sb.append("parent=" + parent.getClass().getSimpleName() + " "); - if (child != null) { - sb.append("child=" + child.getClass().getSimpleName() + " "); - final NodeFieldAccessor field = NodeUtil.findChildField(parent, child); - if (field != null) { - sb.append("field=" + field.getName() + " "); - } - } - } - if (wrapper != null) { - sb.append("wrapper=" + wrapper.getClass().getSimpleName()); - } - return sb.toString(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * An observer of events related to {@link Probe}s: creating and tagging. - */ -public interface ProbeListener { - - /** - * Notifies that all registered {@link ASTProber}s are about to be applied to a newly - * constructed AST. - * - * @param source source code from which the AST was constructed - */ - void startASTProbing(Source source); - - /** - * Notifies that a {@link Probe} has been newly attached to an AST via {@link Node#probe()}. - *

- * There can be no more than one {@link Probe} at a node; this notification will only be - * delivered the first time {@linkplain Node#probe() probe()} is called at a particular AST - * node. There will also be no notification when the AST to which the Probe is attached is - * cloned. - */ - void newProbeInserted(Probe probe); - - /** - * Notifies that a {@link SyntaxTag} has been newly added to the set of tags associated with a - * {@link Probe} via {@link Probe#tagAs(SyntaxTag, Object)}. - *

- * The {@linkplain SyntaxTag tags} at a {@link Probe} are a set; this notification will - * only be delivered the first time a particular {@linkplain SyntaxTag tag} is added at a - * {@link Probe}. - *

- * An optional value supplied with {@linkplain Probe#tagAs(SyntaxTag, Object) tagAs(SyntaxTag, - * Object)} is reported to all listeners, but not stored. As a consequence, the optional value - * will have no effect at all if the tag had already been added. - * - * @param probe where a tag has been added - * @param tag the tag that has been newly added (subsequent additions of the tag are - * unreported). - * @param tagValue an optional value associated with the tag for the purposes of reporting. - */ - void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue); - - /** - * Notifies that the application of all registered {@link ASTProber}s to a newly constructed AST - * has completed. - * - * @param source source code from which the AST was constructed - */ - void endASTProbing(Source source); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.Instrument.AbstractInstrumentNode; -import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Implementation class & interface for enabling the attachment of {@linkplain Probe Probes} to - * Truffle ASTs. - *

- * A {@link ProbeNode} is the head of a chain of nodes acting on behalf of {@linkplain Instrument - * instruments}. It is attached to an AST as a child of a guest-language-specific - * {@link WrapperNode} node. - *

- * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument instruments} - * will be cloned along with the {@link WrapperNode} to which it is attached. An instance of - * {@link Probe} represents abstractly the instrumentation at a particular location in a Guest - * Language AST, tracks the clones of the chain, and keeps the instrumentation attached to the - * clones consistent. - */ -@NodeInfo(cost = NodeCost.NONE) -public final class ProbeNode extends Node implements TruffleEvents, InstrumentationNode { - - /** - * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument - * instrumentation} at a particular Guest Language (GL) node. Implementations must extend - * {@link Node} and should override {@link Node#isInstrumentable()} to return {@code false}. - *

- * The implementation must be GL-specific. A wrapper decorates a GL AST node (the - * wrapper's child) by acting as a transparent proxy with respect to the GL's - * execution semantics. - *

- * Instrumentation at the wrapped node is implemented by an instance of {@link ProbeNode} - * attached as a second child of the {@link WrapperNode}. - *

- * A wrapper is obliged to notify its attached {@link ProbeNode} when execution events occur at - * the wrapped AST node during program execution. - *

- * When a GL AST is cloned, the {@link WrapperNode}, its {@link ProbeNode} and any - * {@linkplain Instrument instrumentation} are also cloned; they are in effect part of the GL - * AST. An instance of {@link Probe} represents abstractly the instrumentation at a particular - * location in a GL AST; it tracks all the copies of the Wrapper and attached instrumentation, - * and acts as a single point of access for tools. - *

- * This interface is not intended to be visible as part of the API for tools (instrumentation - * clients). - *

- * Implementation guidelines: - *

    - *
  1. Each GL implementation should include a WrapperNode implementation; usually only one is - * needed.
  2. - *
  3. The wrapper type should descend from the GL-specific node class.
  4. - *
  5. Must have a field: {@code @Child private Node child;}
  6. - *
  7. Must have a field: {@code @Child private ProbeNode probeNode;}
  8. - *
  9. The wrapper must act as a proxy for its child, which means implementing every - * possible execute- method that gets called on guest language AST node types by their - * parents, and passing along each call to its child.
  10. - *
  11. Method {@code Probe getProbe()} should be implemented as {@code probeNode.getProbe();} - *
  12. Method {@code insertProbe(ProbeNode)} should be implemented as - * {@code this.probeNode=insert(newProbeNode);}
  13. - *
  14. Most importantly, Wrappers must be implemented so that Truffle optimization will reduce - * their runtime overhead to zero when there are no attached {@link Instrument}s.
  15. - *
- *

- * - * @see Instrument - */ - public interface WrapperNode extends InstrumentationNode { - - /** - * Gets the node being "wrapped", i.e. the AST node for which - * {@linkplain InstrumentationNode.TruffleEvents execution events} will be reported through - * the Instrumentation Framework. - */ - Node getChild(); - - /** - * Gets the {@link Probe} responsible for installing this wrapper. - */ - Probe getProbe(); - - /** - * Implementation support for completing a newly created wrapper node. - */ - void insertProbe(ProbeNode probeNode); - } - - /** - * Create a new {@link Probe} associated with, and attached to, a Guest Language specific - * instance of {@link WrapperNode}. - */ - public static Probe insertProbe(WrapperNode wrapper) { - final SourceSection sourceSection = wrapper.getChild().getSourceSection(); - final ProbeNode probeNode = new ProbeNode(); // private constructor - probeNode.probe = new Probe(probeNode, sourceSection); // package private access - wrapper.insertProbe(probeNode); - return probeNode.probe; - } - - // Never changed once set. - @CompilationFinal Probe probe = null; - /** - * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in chain. - */ - @Child protected AbstractInstrumentNode firstInstrumentNode; - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public Node copy() { - Node node = super.copy(); - probe.registerProbeNodeClone((ProbeNode) node); - return node; - } - - /** - * @return the {@link Probe} permanently associated with this {@link ProbeNode}. - */ - public Probe getProbe() { - return probe; - } - - public void enter(Node node, VirtualFrame vFrame) { - this.probe.checkProbeUnchanged(); - final SyntaxTagTrap beforeTagTrap = probe.getBeforeTrap(); - if (beforeTagTrap != null) { - beforeTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); - } - if (firstInstrumentNode != null) { - firstInstrumentNode.enter(node, vFrame); - } - } - - public void returnVoid(Node node, VirtualFrame vFrame) { - this.probe.checkProbeUnchanged(); - if (firstInstrumentNode != null) { - firstInstrumentNode.returnVoid(node, vFrame); - } - final SyntaxTagTrap afterTagTrap = probe.getAfterTrap(); - if (afterTagTrap != null) { - afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); - } - } - - public void returnValue(Node node, VirtualFrame vFrame, Object result) { - this.probe.checkProbeUnchanged(); - if (firstInstrumentNode != null) { - firstInstrumentNode.returnValue(node, vFrame, result); - } - final SyntaxTagTrap afterTagTrap = probe.getAfterTrap(); - if (afterTagTrap != null) { - afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); - } - } - - public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { - this.probe.checkProbeUnchanged(); - if (firstInstrumentNode != null) { - firstInstrumentNode.returnExceptional(node, vFrame, exception); - } - final SyntaxTagTrap afterTagTrap = probe.getAfterTrap(); - if (afterTagTrap != null) { - afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); - } - } - - public String instrumentationInfo() { - return "Standard probe"; - } - - /** - * Gets the guest-language AST node to which this Probe is attached. - */ - Node getProbedNode() { - return ((WrapperNode) this.getParent()).getChild(); - } - - /** - * Adds an {@link AbstractInstrumentNode} to this chain. - */ - @TruffleBoundary - void addInstrument(Instrument instrument) { - assert instrument.getProbe() == probe; - // The existing chain of nodes may be empty - // Attach the modified chain. - firstInstrumentNode = insert(instrument.addToChain(firstInstrumentNode)); - } - - /** - * Removes an instrument from this chain of instruments. - * - * @throws RuntimeException if no matching instrument is found, - */ - @TruffleBoundary - void removeInstrument(Instrument instrument) { - assert instrument.getProbe() == probe; - final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrumentNode); - if (modifiedChain == null) { - firstInstrumentNode = null; - } else { - firstInstrumentNode = insert(modifiedChain); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nodes.*; - -/** - * Controls breaking out of all executions and ending Truffle execution. - */ -public final class QuitException extends ControlFlowException { - - private static final long serialVersionUID = -4301115629772778413L; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SimpleInstrumentListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SimpleInstrumentListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.source.*; - -/** - * A receiver of Truffle execution events that can act on behalf of an external client. - *

- * The {@link Probe} instance provides access to the {@link SourceSection} associated with the - * event, as well as any {@link SyntaxTag}s that have been applied at that program's location. - *

- * This is the simplest kind of listener, suitable for clients that need no other information about - * the program's execution state at the time of the event. Clients that require access to the AST - * execution state should use {@link StandardInstrumentListener}. - *

- * Clients are free, of course, to record additional information in the listener implementation that - * carries additional information about the context and reason for the particular {@link Instrument} - * that is to be created from the listener. - */ -public interface SimpleInstrumentListener { - - /** - * Receive notification that a program location is about to be executed. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void enter(Probe probe); - - /** - * Receive notification that a program location's {@code void}-valued execution has just - * completed. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnVoid(Probe probe); - - /** - * Receive notification that a program location's execution has just completed and returned a - * value (boxed if primitive). - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnValue(Probe probe, Object result); - - /** - * Receive notification that a program location's execution has just thrown an exception. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnExceptional(Probe probe, Exception exception); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardInstrumentListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardInstrumentListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * A receiver of Truffle execution events that can act on behalf of an external client. - *

- * The {@link Probe} argument provides access to the {@link SourceSection} associated with the - * event, as well as any {@link SyntaxTag}s that have been applied at that AST node. - *

- * This listener is designed for clients that also require access to the AST execution state at the - * time of the event. Clients that do not require access to the AST execution state should use the - * {@link SimpleInstrumentListener}. - *

- * Clients are free, of course, to record additional information in the listener implementation that - * carries additional information about the context and reason for the particular {@link Instrument} - * that is to be created from the listener. - */ -public interface StandardInstrumentListener { - - /** - * Receive notification that an AST node's execute method is about to be called. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void enter(Probe probe, Node node, VirtualFrame vFrame); - - /** - * Receive notification that an AST Node's {@code void}-valued execute method has just returned. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnVoid(Probe probe, Node node, VirtualFrame vFrame); - - /** - * Receive notification that an AST Node's execute method has just returned a value (boxed if - * primitive). - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnValue(Probe probe, Node node, VirtualFrame vFrame, Object result); - - /** - * Receive notification that an AST Node's execute method has just thrown an exception. - *

- * Synchronous: Truffle execution waits until the call returns. - */ - void returnExceptional(Probe probe, Node node, VirtualFrame vFrame, Exception exception); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardSyntaxTag.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardSyntaxTag.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * A somewhat language-agnostic set of user-sensible syntactic categories, suitable for conventional - * imperative languages, and is being developed incrementally. - *

- * The need for alternative sets of tags is likely to arise, perhaps for other families of languages - * (for example for mostly expression-oriented languages) or even for specific languages. - * - * @see Probe - */ -public enum StandardSyntaxTag implements SyntaxTag { - - /** - * Marker for a variable assignment. - */ - ASSIGNMENT("assignment", "a variable assignment"), - - /** - * Marker for a call site. - */ - CALL("call", "a method/procedure call site"), - - /** - * Marker for a location where a guest language exception is about to be thrown. - */ - THROW("throw", "creator of an exception"), - - /** - * Marker for a location where ordinary "stepping" should halt. - */ - STATEMENT("statement", "basic unit of the language, suitable for \"stepping\" in a debugger"), - - /** - * Marker for the start of the body of a method. - */ - START_METHOD("start-method", "start of the body of a method"), - - /** - * Marker for the start of the body of a loop. - */ - START_LOOP("start-loop", "start of the body of a loop"), - - /** - * Marker that is attached to some arbitrary locations that appear often-enough in an AST so - * that a location with this tag is regularly executed. Could be the start of method and loop - * bodies. May be used to implement some kind of safepoint functionality. - */ - PERIODIC("periodic", "arbitrary locations that appear often-enough in an AST so that a location with this tag is regularly executed"); - - private final String name; - private final String description; - - private StandardSyntaxTag(String name, String description) { - this.name = name; - this.description = description; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTag.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTag.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Program element "tags", presumed to be singletons (best implemented as enums) that define - * user-visible behavior for debugging and other simple tools. These categories should correspond to - * program structures, for example "statement" and "assignment", that are meaningful - * ("human-sensible") to guest language programmers. - *

- * An untagged Truffle node should be understood as an artifact of the guest language implementation - * and should not be visible to guest language programmers. Nodes may also have more than one tag, - * for example a variable assignment that is also a statement. Finally, the assignment of tags to - * nodes could depending on the use-case of whatever tool is using them. - * - * @see Probe - * @see StandardSyntaxTag - */ -public interface SyntaxTag { - - /** - * Human-friendly name of guest language program elements belonging to the category, e.g. - * "statement". - */ - String name(); - - /** - * Criteria and example uses for the tag. - */ - String getDescription(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A trap that can be set to interrupt execution at probed nodes carrying a specific tag. - * - * @see Probe - */ -public abstract class SyntaxTagTrap { - - private final SyntaxTag tag; - - protected SyntaxTagTrap(SyntaxTag tag) { - this.tag = tag; - } - - public final SyntaxTag getTag() { - return tag; - } - - /** - * Notifies that execution is halted at a node with the specified tag. - */ - public abstract void tagTrappedAt(Node node, MaterializedFrame frame); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ToolSupportProvider.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ToolSupportProvider.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Access to language-specific information and execution services for external tools. - */ -public interface ToolSupportProvider { - - /** - * Gets visualization services for language-specific information. - */ - Visualizer getVisualizer(); - - /** - * Enables AST probing on all subsequently created ASTs (sources parsed). - * - * @param astProber optional AST prober to enable; the default for the language used if - * {@code null} - */ - void enableASTProbing(ASTProber astProber); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Visualization services for the benefit of instrumentation-based tools, possibly specialized for - * each guest language and possibly specialized for relevant information from the underlying Truffle - * implementation. - *

- * Disclaimer: experimental interface under development. - */ -public interface Visualizer { - - // TODO (mlvdv) "Visualizer" is misleading: rename. - /** - * Gets a printer for Truffle ASTs, possibly specialized to be helpful for a specific guest - * language implementation. - */ - ASTPrinter getASTPrinter(); - - /** - * A short description of a source location in terms of source + line number. - */ - String displaySourceLocation(Node node); - - /** - * Describes the name of the method containing a node. - */ - String displayMethodName(Node node); - - /** - * The name of the method. - */ - String displayCallTargetName(CallTarget callTarget); - - /** - * Converts a value in the guest language to a display string. If - * - * @param trim if {@code > 0}, them limit size of String to either the value of trim or the - * number of characters in the first line, whichever is lower. - */ - String displayValue(Object value, int trim); - - /** - * Converts a slot identifier in the guest language to a display string. - */ - String displayIdentifier(FrameSlot slot); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; -import com.oracle.truffle.api.source.*; - -/** - * A language-agnostic for printing out various pieces of a Truffle AST. - */ -public class DefaultASTPrinter implements ASTPrinter { - - public DefaultASTPrinter() { - } - - public void printTree(PrintWriter p, Node node, int maxDepth, Node markNode) { - printTree(p, node, maxDepth, markNode, 1); - p.println(); - p.flush(); - } - - public String printTreeToString(Node node, int maxDepth, Node markNode) { - StringWriter out = new StringWriter(); - printTree(new PrintWriter(out), node, maxDepth, markNode); - return out.toString(); - } - - public String printTreeToString(Node node, int maxDepth) { - return printTreeToString(node, maxDepth, null); - } - - public String printNodeWithInstrumentation(Node node) { - if (node == null) { - return "null"; - } - final StringBuilder sb = new StringBuilder(); - sb.append(nodeName(node)); - sb.append("("); - if (node instanceof InstrumentationNode) { - sb.append(instrumentInfo((InstrumentationNode) node)); - } - sb.append(sourceInfo(node)); - sb.append(NodeUtil.printSyntaxTags(node)); - sb.append(")"); - final Node parent = node.getParent(); - if (parent instanceof WrapperNode) { - final WrapperNode wrapper = (WrapperNode) parent; - sb.append(" Probed"); - sb.append(NodeUtil.printSyntaxTags(wrapper)); - } - return sb.toString(); - } - - protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { - if (node == null) { - p.print("null"); - return; - } - - p.print(nodeName(node)); - - p.print("("); - - if (node instanceof InstrumentationNode) { - p.print(instrumentInfo((InstrumentationNode) node)); - } - - p.print(sourceInfo(node)); - - p.print(NodeUtil.printSyntaxTags(node)); - - ArrayList childFields = new ArrayList<>(); - - for (NodeFieldAccessor field : NodeClass.get(node).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { - childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { - // p.print(sep); - // sep = ", "; - // - // final String fieldName = field.getName(); - // switch (fieldName) { - // - // } - // p.print(fieldName); - // p.print(" = "); - // p.print(field.loadValue(node)); - } - } - p.print(")"); - - if (level <= maxDepth) { - - if (childFields.size() != 0) { - p.print(" {"); - for (NodeFieldAccessor field : childFields) { - - Object value = field.loadValue(node); - if (value == null) { - printNewLine(p, level); - p.print(field.getName()); - p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { - printChild(p, maxDepth, markNode, level, field, value); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - printChildren(p, maxDepth, markNode, level, field, value); - } else { - printNewLine(p, level); - p.print(field.getName()); - } - } - printNewLine(p, level - 1); - p.print("}"); - } - } - } - - protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { - printNewLine(p, level); - p.print(field.getName()); - Node[] children = (Node[]) value; - p.print(" = ["); - String sep = ""; - for (Node child : children) { - p.print(sep); - sep = ", "; - printTree(p, child, maxDepth, markNode, level + 1); - } - p.print("]"); - } - - protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { - final Node valueNode = (Node) value; - printNewLine(p, level, valueNode == markNode); - p.print(field.getName()); - p.print(" = "); - printTree(p, valueNode, maxDepth, markNode, level + 1); - } - - protected static void printNewLine(PrintWriter p, int level, boolean mark) { - p.println(); - for (int i = 0; i < level; i++) { - if (mark && i == 0) { - p.print(" -->"); - } else { - p.print(" "); - } - } - } - - protected static void printNewLine(PrintWriter p, int level) { - printNewLine(p, level, false); - } - - protected static String nodeName(Node node) { - return node.getClass().getSimpleName(); - } - - protected static String sourceInfo(Node node) { - final SourceSection src = node.getSourceSection(); - if (src != null) { - if (src instanceof NullSourceSection) { - final NullSourceSection nullSection = (NullSourceSection) src; - return nullSection.getShortDescription(); - } else { - return src.getSource().getName() + ":" + src.getStartLine(); - } - } - return ""; - } - - protected static String instrumentInfo(InstrumentationNode node) { - final String info = node.instrumentationInfo(); - return info == null ? "" : info; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultProbeListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultProbeListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -public abstract class DefaultProbeListener implements ProbeListener { - - public void startASTProbing(Source source) { - } - - public void newProbeInserted(Probe probe) { - } - - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - } - - public void endASTProbing(Source source) { - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultSimpleInstrumentListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultSimpleInstrumentListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.instrument.*; - -/** - * A listener for Truffle execution events that provides a no-op implementation of every event. - */ -public class DefaultSimpleInstrumentListener implements SimpleInstrumentListener { - - public void enter(Probe probe) { - } - - public void returnVoid(Probe probe) { - } - - public void returnValue(Probe probe, Object result) { - } - - public void returnExceptional(Probe probe, Exception exception) { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultStandardInstrumentListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultStandardInstrumentListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A listener for AST {@linkplain StandardInstrumentListener execution events} that provides a no-op - * implementation of every event. - */ -public class DefaultStandardInstrumentListener implements StandardInstrumentListener { - - public void enter(Probe probe, Node node, VirtualFrame vFrame) { - } - - public void returnVoid(Probe probe, Node node, VirtualFrame vFrame) { - } - - public void returnValue(Probe probe, Node node, VirtualFrame vFrame, Object result) { - } - - public void returnExceptional(Probe probe, Node node, VirtualFrame vFrame, Exception exception) { - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -public class DefaultVisualizer implements Visualizer { - - private final ASTPrinter astPrinter; - - public DefaultVisualizer() { - this.astPrinter = new DefaultASTPrinter(); - } - - public ASTPrinter getASTPrinter() { - return astPrinter; - } - - public String displaySourceLocation(Node node) { - if (node == null) { - return ""; - } - SourceSection section = node.getSourceSection(); - boolean estimated = false; - if (section == null) { - section = node.getEncapsulatingSourceSection(); - estimated = true; - } - if (section == null) { - return ""; - } - return section.getShortDescription() + (estimated ? "~" : ""); - } - - public String displayMethodName(Node node) { - if (node == null) { - return null; - } - RootNode root = node.getRootNode(); - if (root == null) { - return "unknown"; - } - return root.getCallTarget().toString(); - } - - public String displayCallTargetName(CallTarget callTarget) { - return callTarget.toString(); - } - - public String displayValue(Object value, int trim) { - return trim(value.toString(), trim); - } - - public String displayIdentifier(FrameSlot slot) { - return slot.getIdentifier().toString(); - } - - /** - * Trims text if {@code trim > 0} to the shorter of {@code trim} or the length of the first line - * of test. Identity if {@code trim <= 0}. - */ - protected String trim(String text, int trim) { - if (trim == 0) { - return text; - } - final String[] lines = text.split("\n"); - String result = lines[0]; - if (lines.length == 1) { - if (result.length() <= trim) { - return result; - } - if (trim <= 3) { - return result.substring(0, Math.min(result.length() - 1, trim - 1)); - } else { - return result.substring(0, trim - 4) + "..."; - } - } - return (result.length() < trim - 3 ? result : result.substring(0, trim - 4)) + "..."; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ControlFlowException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ControlFlowException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * An exception thrown to model control flow in a Truffle interpreter. The Truffle optimizer has - * special knowledge of this exception class for performance optimizations. - */ -public class ControlFlowException extends RuntimeException { - - private static final long serialVersionUID = 3676602078425211386L; - - /** - * Creates an exception thrown to model control flow. - */ - public ControlFlowException() { - /* - * We use the super constructor that initializes the cause to null. Without that, the cause - * would be this exception itself. This helps escape analysis: it avoids the circle of an - * object pointing to itself. - */ - super((Throwable) null); - } - - /** - * For performance reasons, this exception does not record any stack trace information. - */ - @SuppressWarnings("sync-override") - @Override - public final Throwable fillInStackTrace() { - return null; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.frame.*; - -/** - * Represents a direct call to a {@link CallTarget}. Direct calls are calls for which the - * {@link CallTarget} remains the same for each consecutive call. This part of the Truffle API - * enables the runtime system to perform additional optimizations on direct calls. - * - * Optimizations that can be applied to a {@link DirectCallNode} are inlining and call site - * sensitive AST duplication. Inlining inlines this call site into the call graph of the parent - * {@link CallTarget}. Call site sensitive AST duplication duplicates the {@link CallTarget} in an - * uninitialized state to collect call site sensitive profiling information. - * - * Please note: This class is not intended to be subclassed by guest language implementations. - * - * @see IndirectCallNode for calls with a non-constant target - * @see TruffleRuntime#createDirectCallNode(CallTarget) - * @see #forceInlining() - * @see #cloneCallTarget() - */ -public abstract class DirectCallNode extends Node { - - protected final CallTarget callTarget; - - protected DirectCallNode(CallTarget callTarget) { - this.callTarget = callTarget; - } - - /** - * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}. - * - * @param arguments the arguments that should be passed to the callee - * @return the return result of the call - */ - public abstract Object call(VirtualFrame frame, Object[] arguments); - - /** - * Returns the originally supplied {@link CallTarget} when this call node was created. Please - * note that the returned {@link CallTarget} is not necessarily the {@link CallTarget} that is - * called. For that use {@link #getCurrentCallTarget()} instead. - * - * @return the {@link CallTarget} provided. - */ - public CallTarget getCallTarget() { - return callTarget; - } - - /** - * Returns true if the underlying runtime system supports inlining for the - * {@link CallTarget} in this {@link DirectCallNode}. - * - * @return true if inlining is supported. - */ - public abstract boolean isInlinable(); - - /** - * Returns true if the {@link CallTarget} is forced to be inlined. A - * {@link DirectCallNode} can either be inlined manually by invoking {@link #forceInlining()} or - * by the runtime system which may at any point decide to inline. - * - * @return true if this method was inlined else false. - */ - public abstract boolean isInliningForced(); - - /** - * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the - * runtime system does not support inlining or it is already inlined this method has no effect. - * The runtime system may decide to not inline calls which were forced to inline. - */ - public abstract void forceInlining(); - - /** - * Returns true if the runtime system has decided to inline this call-site. If the - * {@link DirectCallNode} was forced to inline then this does not necessarily mean that the - * {@link DirectCallNode} is really going to be inlined. This depends on whether or not the - * runtime system supports inlining. The runtime system may also decide to not inline calls - * which were forced to inline. - * - * @deprecated we do not expose this information any longer. returns always false. - */ - @SuppressWarnings("static-method") - @Deprecated - public final boolean isInlined() { - return false; - } - - /** - * Returns true if the runtime system supports cloning and the {@link RootNode} - * returns true in {@link RootNode#isCloningAllowed()}. - * - * @return true if the target is allowed to be cloned. - */ - public abstract boolean isCallTargetCloningAllowed(); - - /** - * Clones the {@link CallTarget} instance returned by {@link #getCallTarget()} in an - * uninitialized state for this {@link DirectCallNode}. This can be sensible to gather call site - * sensitive profiling information for this {@link DirectCallNode}. If - * {@link #isCallTargetCloningAllowed()} returns false this method has no effect - * and returns false. - */ - public abstract boolean cloneCallTarget(); - - /** - * Returns true if the target of the {@link DirectCallNode} was cloned by the - * runtime system or by the guest language implementation. - * - * @return if the target was split - */ - public final boolean isCallTargetCloned() { - return getClonedCallTarget() != null; - } - - /** - * Returns the split {@link CallTarget} if this call site's {@link CallTarget} is cloned. - * - * @return the split {@link CallTarget} - */ - public abstract CallTarget getClonedCallTarget(); - - /** - * Returns the used call target when {@link #call(VirtualFrame, Object[])} is invoked. If the - * {@link CallTarget} was split this method returns the {@link CallTarget} returned by - * {@link #getClonedCallTarget()}. - * - * @return the used {@link CallTarget} when node is called - */ - public CallTarget getCurrentCallTarget() { - CallTarget split = getClonedCallTarget(); - if (split != null) { - return split; - } else { - return getCallTarget(); - } - } - - /** - * Returns the {@link RootNode} associated with {@link CallTarget} returned by - * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a - * {@link RootNode} this method returns null. - * - * @see #getCurrentCallTarget() - * @return the root node of the used call target - */ - public final RootNode getCurrentRootNode() { - CallTarget target = getCurrentCallTarget(); - if (target instanceof RootCallTarget) { - return ((RootCallTarget) target).getRootNode(); - } - return null; - } - - @Override - public String toString() { - return String.format("%s(target=%s)", getClass().getSimpleName(), getCurrentCallTarget()); - } - - public static DirectCallNode create(CallTarget target) { - return Truffle.getRuntime().createDirectCallNode(target); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ExplodeLoop.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ExplodeLoop.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.lang.annotation.*; - -/** - * Specifies for a method that the loops with constant number of invocations should be fully - * unrolled. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface ExplodeLoop { - boolean merge() default false; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,420 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.io.*; -import java.lang.annotation.*; -import java.net.*; -import java.util.*; - -import javax.xml.parsers.*; -import javax.xml.transform.*; -import javax.xml.transform.dom.*; -import javax.xml.transform.stream.*; - -import org.w3c.dom.*; - -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; - -/** - * Utility class for creating output for the ideal graph visualizer. - */ -public class GraphPrintVisitor { - - public static final String GraphVisualizerAddress = "127.0.0.1"; - public static final int GraphVisualizerPort = 4444; - - private Document dom; - private Map nodeMap; - private List edgeList; - private Map prevNodeMap; - private int id; - private Element graphDocument; - private Element groupElement; - private Element graphElement; - private Element nodesElement; - private Element edgesElement; - - public GraphPrintVisitor() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - try { - DocumentBuilder db = dbf.newDocumentBuilder(); - - dom = db.newDocument(); - } catch (ParserConfigurationException ex) { - throw new RuntimeException(ex); - } - - graphDocument = dom.createElement("graphDocument"); - dom.appendChild(graphDocument); - } - - public GraphPrintVisitor beginGroup(String groupName) { - groupElement = dom.createElement("group"); - graphDocument.appendChild(groupElement); - Element properties = dom.createElement("properties"); - groupElement.appendChild(properties); - - if (!groupName.isEmpty()) { - // set group name - Element propName = dom.createElement("p"); - propName.setAttribute("name", "name"); - propName.setTextContent(groupName); - properties.appendChild(propName); - } - - // forget old nodes - nodeMap = prevNodeMap = null; - edgeList = null; - - return this; - } - - public GraphPrintVisitor beginGraph(String graphName) { - if (null == groupElement) { - beginGroup(""); - } else if (null != prevNodeMap) { - // TODO: difference (create removeNode,removeEdge elements) - } - - graphElement = dom.createElement("graph"); - groupElement.appendChild(graphElement); - Element properties = dom.createElement("properties"); - graphElement.appendChild(properties); - nodesElement = dom.createElement("nodes"); - graphElement.appendChild(nodesElement); - edgesElement = dom.createElement("edges"); - graphElement.appendChild(edgesElement); - - // set graph name - Element propName = dom.createElement("p"); - propName.setAttribute("name", "name"); - propName.setTextContent(graphName); - properties.appendChild(propName); - - // save old nodes - prevNodeMap = nodeMap; - nodeMap = new IdentityHashMap<>(); - edgeList = new ArrayList<>(); - - return this; - } - - @Override - public String toString() { - if (null != dom) { - try { - Transformer tr = TransformerFactory.newInstance().newTransformer(); - tr.setOutputProperty(OutputKeys.INDENT, "yes"); - tr.setOutputProperty(OutputKeys.METHOD, "xml"); - tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - - StringWriter strWriter = new StringWriter(); - tr.transform(new DOMSource(dom), new StreamResult(strWriter)); - return strWriter.toString(); - } catch (TransformerException e) { - e.printStackTrace(); - } - } - return ""; - } - - public void printToFile(File f) { - try { - Transformer tr = TransformerFactory.newInstance().newTransformer(); - tr.setOutputProperty(OutputKeys.INDENT, "yes"); - tr.setOutputProperty(OutputKeys.METHOD, "xml"); - tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - - tr.transform(new DOMSource(dom), new StreamResult(new FileOutputStream(f))); - } catch (TransformerException | FileNotFoundException e) { - e.printStackTrace(); - } - } - - public void printToSysout() { - try { - Transformer tr = TransformerFactory.newInstance().newTransformer(); - tr.setOutputProperty(OutputKeys.INDENT, "yes"); - tr.setOutputProperty(OutputKeys.METHOD, "xml"); - tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - - tr.transform(new DOMSource(dom), new StreamResult(System.out)); - } catch (TransformerException e) { - e.printStackTrace(); - } - } - - public void printToNetwork(boolean ignoreErrors) { - try { - Transformer tr = TransformerFactory.newInstance().newTransformer(); - tr.setOutputProperty(OutputKeys.METHOD, "xml"); - - Socket socket = new Socket(GraphVisualizerAddress, GraphVisualizerPort); - BufferedOutputStream stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000); - tr.transform(new DOMSource(dom), new StreamResult(stream)); - } catch (TransformerException | IOException e) { - if (!ignoreErrors) { - e.printStackTrace(); - } - } - } - - private String nextId() { - return String.valueOf(id++); - } - - private String oldOrNextId(Object node) { - if (null != prevNodeMap && prevNodeMap.containsKey(node)) { - Element nodeElem = prevNodeMap.get(node); - return nodeElem.getAttribute("id"); - } else { - return nextId(); - } - } - - protected Element getElementByObject(Object op) { - return nodeMap.get(op); - } - - protected void createElementForNode(Object node) { - boolean exists = nodeMap.containsKey(node); - if (!exists || NodeUtil.findAnnotation(node.getClass(), GraphDuplicate.class) != null) { - Element nodeElem = dom.createElement("node"); - nodeElem.setAttribute("id", !exists ? oldOrNextId(node) : nextId()); - nodeMap.put(node, nodeElem); - Element properties = dom.createElement("properties"); - nodeElem.appendChild(properties); - nodesElement.appendChild(nodeElem); - - setNodeProperty(node, "name", node.getClass().getSimpleName().replaceFirst("Node$", "")); - NodeInfo nodeInfo = node.getClass().getAnnotation(NodeInfo.class); - if (nodeInfo != null) { - setNodeProperty(node, "cost", nodeInfo.cost()); - if (!nodeInfo.shortName().isEmpty()) { - setNodeProperty(node, "shortName", nodeInfo.shortName()); - } - } - setNodeProperty(node, "class", node.getClass().getSimpleName()); - if (node instanceof Node) { - readNodeProperties((Node) node); - copyDebugProperties((Node) node); - } - } - } - - private Element getPropertyElement(Object node, String propertyName) { - Element nodeElem = getElementByObject(node); - Element propertiesElem = (Element) nodeElem.getElementsByTagName("properties").item(0); - if (propertiesElem == null) { - return null; - } - - NodeList propList = propertiesElem.getElementsByTagName("p"); - for (int i = 0; i < propList.getLength(); i++) { - Element p = (Element) propList.item(i); - if (propertyName.equals(p.getAttribute("name"))) { - return p; - } - } - return null; - } - - protected void setNodeProperty(Object node, String propertyName, Object value) { - Element nodeElem = getElementByObject(node); - Element propElem = getPropertyElement(node, propertyName); // if property exists, replace - // its value - if (null == propElem) { // if property doesn't exist, create one - propElem = dom.createElement("p"); - propElem.setAttribute("name", propertyName); - nodeElem.getElementsByTagName("properties").item(0).appendChild(propElem); - } - propElem.setTextContent(String.valueOf(value)); - } - - private void copyDebugProperties(Node node) { - Map debugProperties = node.getDebugProperties(); - for (Map.Entry property : debugProperties.entrySet()) { - setNodeProperty(node, property.getKey(), property.getValue()); - } - } - - private void readNodeProperties(Node node) { - NodeFieldAccessor[] fields = node.getNodeClass().getFields(); - for (NodeFieldAccessor field : fields) { - if (field.getKind() == NodeFieldKind.DATA) { - String key = field.getName(); - if (getPropertyElement(node, key) == null) { - Object value = field.loadValue(node); - setNodeProperty(node, key, value); - } - } - } - } - - protected void connectNodes(Object a, Object b, String label) { - if (nodeMap.get(a) == null || nodeMap.get(b) == null) { - return; - } - - String fromId = nodeMap.get(a).getAttribute("id"); - String toId = nodeMap.get(b).getAttribute("id"); - - // count existing to-edges - int count = 0; - for (Element e : edgeList) { - if (e.getAttribute("to").equals(toId)) { - ++count; - } - } - - Element edgeElem = dom.createElement("edge"); - edgeElem.setAttribute("from", fromId); - edgeElem.setAttribute("to", toId); - edgeElem.setAttribute("index", String.valueOf(count)); - if (label != null) { - edgeElem.setAttribute("label", label); - } - edgesElement.appendChild(edgeElem); - edgeList.add(edgeElem); - } - - public GraphPrintVisitor visit(Object node) { - if (null == graphElement) { - beginGraph("truffle tree"); - } - - // if node is visited once again, skip - if (getElementByObject(node) != null && NodeUtil.findAnnotation(node.getClass(), GraphDuplicate.class) == null) { - return this; - } - - // respect node's custom handler - if (NodeUtil.findAnnotation(node.getClass(), CustomGraphPrintHandler.class) != null) { - Class customHandlerClass = NodeUtil.findAnnotation(node.getClass(), CustomGraphPrintHandler.class).handler(); - try { - GraphPrintHandler customHandler = customHandlerClass.newInstance(); - customHandler.visit(node, new GraphPrintAdapter()); - } catch (InstantiationException | IllegalAccessException e) { - assert false : e; - } - } else if (NodeUtil.findAnnotation(node.getClass(), NullGraphPrintHandler.class) != null) { - // ignore - } else { - // default handler - createElementForNode(node); - - if (node instanceof Node) { - for (Map.Entry child : findNamedNodeChildren((Node) node).entrySet()) { - visit(child.getValue()); - connectNodes(node, child.getValue(), child.getKey()); - } - } - } - - return this; - } - - private static LinkedHashMap findNamedNodeChildren(Node node) { - LinkedHashMap nodes = new LinkedHashMap<>(); - NodeClass nodeClass = node.getNodeClass(); - - for (NodeFieldAccessor field : nodeClass.getFields()) { - NodeFieldKind kind = field.getKind(); - if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) { - Object value = field.loadValue(node); - if (value != null) { - if (kind == NodeFieldKind.CHILD) { - nodes.put(field.getName(), (Node) value); - } else if (kind == NodeFieldKind.CHILDREN) { - Object[] children = (Object[]) value; - for (int i = 0; i < children.length; i++) { - if (children[i] != null) { - nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); - } - } - } - } - } - } - - return nodes; - } - - public class GraphPrintAdapter { - - public void createElementForNode(Object node) { - GraphPrintVisitor.this.createElementForNode(node); - } - - public void visit(Object node) { - GraphPrintVisitor.this.visit(node); - } - - public void connectNodes(Object node, Object child) { - GraphPrintVisitor.this.connectNodes(node, child, null); - } - - public void setNodeProperty(Object node, String propertyName, Object value) { - GraphPrintVisitor.this.setNodeProperty(node, propertyName, value); - } - } - - public interface GraphPrintHandler { - - void visit(Object node, GraphPrintAdapter gPrinter); - } - - public interface ChildSupplier { - - /** Supplies an additional child if available. */ - Object startNode(Object callNode); - - void endNode(Object callNode); - - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface CustomGraphPrintHandler { - - Class handler(); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface NullGraphPrintHandler { - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface GraphDuplicate { - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface HiddenField { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/IndirectCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/IndirectCallNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.frame.*; - -/** - * Represents an indirect call to a {@link CallTarget}. Indirect calls are calls for which the - * {@link CallTarget} may change dynamically for each consecutive call. This part of the Truffle API - * enables the runtime system to perform additional optimizations on indirect calls. - * - * Please note: This class is not intended to be sub classed by guest language implementations. - * - * @see DirectCallNode for faster calls with a constantly known {@link CallTarget}. - */ -public abstract class IndirectCallNode extends Node { - - /** - * Performs an indirect call to the given {@link CallTarget} target with the provided arguments. - * - * @param frame the caller frame - * @param target the {@link CallTarget} to call - * @param arguments the arguments to provide - * @return the return value of the call - */ - public abstract Object call(VirtualFrame frame, CallTarget target, Object[] arguments); - - public static IndirectCallNode create() { - return Truffle.getRuntime().createIndirectCallNode(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InvalidAssumptionException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InvalidAssumptionException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * An exception that should be thrown if an assumption is checked and the check fails. The Truffle - * optimizer has special knowledge of this exception class and will never compile a catch block that - * catches this exception type. - */ -public final class InvalidAssumptionException extends SlowPathException { - - private static final long serialVersionUID = -6801338218909717979L; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/LoopNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/LoopNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; - -/** - * Experimental API: may change significantly without notice. - */ -public abstract class LoopNode extends Node { - - public abstract void executeLoop(VirtualFrame frame); - - public abstract RepeatingNode getRepeatingNode(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,588 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.lang.annotation.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; - -/** - * Abstract base class for all Truffle nodes. - */ -public abstract class Node implements NodeInterface, Cloneable { - - private final NodeClass nodeClass; - @CompilationFinal private Node parent; - @CompilationFinal private SourceSection sourceSection; - - /** - * Marks array fields that are children of this node. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.FIELD}) - public @interface Children { - } - - /** - * Marks fields that represent child nodes of this node. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.FIELD}) - public @interface Child { - } - - protected Node() { - this(null); - } - - protected Node(SourceSection sourceSection) { - CompilerAsserts.neverPartOfCompilation(); - this.sourceSection = sourceSection; - this.nodeClass = NodeClass.get(getClass()); - if (TruffleOptions.TraceASTJSON) { - JSONHelper.dumpNewNode(this); - } - } - - /** - * Assigns a link to a guest language source section to this node. - * - * @param section the object representing a section in guest language source code - */ - public final void assignSourceSection(SourceSection section) { - if (sourceSection != null) { - // Patch this test during the transition to constructor-based - // source attribution, which would otherwise trigger this - // exception. This method will eventually be deprecated. - if (getSourceSection() != section) { - throw new IllegalStateException("Source section is already assigned. Old: " + getSourceSection() + ", new: " + section); - } - } - this.sourceSection = section; - } - - NodeClass getNodeClass() { - return nodeClass; - } - - /** - * Returns a rough estimate for the cost of this {@link Node}. This estimate can be used by - * runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method - * is intended to be overridden by subclasses. The default implementation returns the value of - * {@link NodeInfo#cost()} of the {@link NodeInfo} annotation declared at the subclass. If no - * {@link NodeInfo} annotation is declared the method returns {@link NodeCost#MONOMORPHIC} as a - * default value. - */ - public NodeCost getCost() { - NodeInfo info = getClass().getAnnotation(NodeInfo.class); - if (info != null) { - return info.cost(); - } - return NodeCost.MONOMORPHIC; - } - - /** - * Clears any previously assigned guest language source code from this node. - */ - public final void clearSourceSection() { - this.sourceSection = null; - } - - /** - * Retrieves the segment of guest language source code that is represented by this Node. - * - * @return the source code represented by this Node - */ - public final SourceSection getSourceSection() { - return sourceSection; - } - - /** - * Retrieves the segment of guest language source code that is represented by this Node, if - * present; otherwise retrieves the segment represented by the nearest AST ancestor that has - * this information. - * - * @return an approximation of the source code represented by this Node - */ - @ExplodeLoop - public final SourceSection getEncapsulatingSourceSection() { - Node current = this; - while (current != null) { - if (current.sourceSection != null) { - return current.sourceSection; - } - current = current.parent; - } - return null; - } - - /** - * Method that updates the link to the parent in the array of specified new child nodes to this - * node. - * - * @param newChildren the array of new children whose parent should be updated - * @return the array of new children - */ - protected final T[] insert(final T[] newChildren) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - assert newChildren != null; - for (Node newChild : newChildren) { - adoptHelper(newChild); - } - return newChildren; - } - - /** - * Method that updates the link to the parent in the specified new child node to this node. - * - * @param newChild the new child whose parent should be updated - * @return the new child - */ - protected final T insert(final T newChild) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - assert newChild != null; - adoptHelper(newChild); - return newChild; - } - - public final void adoptChildren() { - CompilerDirectives.transferToInterpreterAndInvalidate(); - adoptHelper(); - } - - private void adoptHelper(final Node newChild) { - assert newChild != null; - if (newChild == this) { - throw new IllegalStateException("The parent of a node can never be the node itself."); - } - newChild.parent = this; - if (TruffleOptions.TraceASTJSON) { - JSONHelper.dumpNewChild(this, newChild); - } - newChild.adoptHelper(); - } - - private void adoptHelper() { - Iterable children = this.getChildren(); - for (Node child : children) { - if (child != null && child.getParent() != this) { - this.adoptHelper(child); - } - } - } - - private void adoptUnadoptedHelper(final Node newChild) { - assert newChild != null; - if (newChild == this) { - throw new IllegalStateException("The parent of a node can never be the node itself."); - } - newChild.parent = this; - newChild.adoptUnadoptedHelper(); - } - - private void adoptUnadoptedHelper() { - Iterable children = this.getChildren(); - for (Node child : children) { - if (child != null && child.getParent() == null) { - this.adoptUnadoptedHelper(child); - } - } - } - - /** - * Returns properties of this node interesting for debugging and can be overwritten by - * subclasses to add their own custom properties. - * - * @return the properties as a key/value hash map - */ - public Map getDebugProperties() { - Map properties = new HashMap<>(); - return properties; - } - - /** - * The current parent node of this node. - * - * @return the parent node - */ - public final Node getParent() { - return parent; - } - - /** - * Replaces this node with another node. If there is a source section (see - * {@link #getSourceSection()}) associated with this node, it is transferred to the new node. - * - * @param newNode the new node that is the replacement - * @param reason a description of the reason for the replacement - * @return the new node - */ - public final T replace(final T newNode, final CharSequence reason) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - atomic(new Runnable() { - public void run() { - replaceHelper(newNode, reason); - } - }); - return newNode; - } - - /** - * Replaces this node with another node. If there is a source section (see - * {@link #getSourceSection()}) associated with this node, it is transferred to the new node. - * - * @param newNode the new node that is the replacement - * @return the new node - */ - public final T replace(T newNode) { - return replace(newNode, ""); - } - - final void replaceHelper(Node newNode, CharSequence reason) { - CompilerAsserts.neverPartOfCompilation(); - assert inAtomicBlock(); - if (this.getParent() == null) { - throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); - } - if (sourceSection != null && newNode.getSourceSection() == null) { - // Pass on the source section to the new node. - newNode.assignSourceSection(sourceSection); - } - // (aw) need to set parent *before* replace, so that (unsynchronized) getRootNode() - // will always find the root node - newNode.parent = this.parent; - if (NodeUtil.replaceChild(this.parent, this, newNode)) { - this.parent.adoptHelper(newNode); - } else { - this.parent.adoptUnadoptedHelper(newNode); - } - reportReplace(this, newNode, reason); - onReplace(newNode, reason); - } - - /** - * Checks if this node can be replaced by another node: tree structure & type. - */ - public final boolean isSafelyReplaceableBy(Node newNode) { - return NodeUtil.isReplacementSafe(getParent(), this, newNode); - } - - private void reportReplace(Node oldNode, Node newNode, CharSequence reason) { - Node node = this; - while (node != null) { - boolean consumed = false; - if (node instanceof ReplaceObserver) { - consumed = ((ReplaceObserver) node).nodeReplaced(oldNode, newNode, reason); - } else if (node instanceof RootNode) { - CallTarget target = ((RootNode) node).getCallTarget(); - if (target instanceof ReplaceObserver) { - consumed = ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason); - } - } - if (consumed) { - break; - } - node = node.getParent(); - } - if (TruffleOptions.TraceRewrites) { - NodeUtil.traceRewrite(this, newNode, reason); - } - if (TruffleOptions.TraceASTJSON) { - JSONHelper.dumpReplaceChild(this, newNode, reason); - } - } - - /** - * Intended to be implemented by subclasses of {@link Node} to receive a notification when the - * node is rewritten. This method is invoked before the actual replace has happened. - * - * @param newNode the replacement node - * @param reason the reason the replace supplied - */ - protected void onReplace(Node newNode, CharSequence reason) { - // empty default - } - - /** - * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all - * child nodes. - * - * @param nodeVisitor the visitor - */ - public final void accept(NodeVisitor nodeVisitor) { - if (nodeVisitor.visit(this)) { - NodeUtil.forEachChildRecursive(this, nodeVisitor); - } - } - - /** - * Iterator over the children of this node. - * - * @return the iterator - */ - public final Iterable getChildren() { - return new Iterable() { - public Iterator iterator() { - return getNodeClass().makeIterator(Node.this); - } - }; - } - - /** - * Creates a shallow copy of this node. - * - * @return the new copy - */ - public Node copy() { - try { - return (Node) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); - } - } - - /** - * Creates a deep copy of this node. - * - * @return the new deep copy - */ - public Node deepCopy() { - return NodeUtil.deepCopyImpl(this); - } - - /** - * This method must never be called. It enforces that {@link Object#clone} is not directly - * called by subclasses. Use the {@link #copy()} method instead. - */ - @Override - @Deprecated - protected final Object clone() throws CloneNotSupportedException { - throw new IllegalStateException("This method should never be called, use the copy method instead!"); - } - - /** - * Get the root node of the tree a node belongs to. - * - * @return the {@link RootNode} or {@code null} if there is none. - */ - public final RootNode getRootNode() { - Node rootNode = this; - while (rootNode.getParent() != null) { - assert !(rootNode instanceof RootNode) : "root node must not have a parent"; - rootNode = rootNode.getParent(); - } - if (rootNode instanceof RootNode) { - return (RootNode) rootNode; - } - return null; - } - - /** - * Any node for which this is {@code true} can be "instrumented" by installing a {@link Probe} - * that intercepts execution events at the node and routes them to any {@link Instrument}s that - * have been attached to the {@link Probe}. Only one {@link Probe} may be installed at each - * node; subsequent calls return the one already installed. - *

- * Note: instrumentation requires a appropriate {@link WrapperNode}, which must be - * provided by {@link #createWrapperNode()}. - * - * @see Instrument - */ - public boolean isInstrumentable() { - return false; - } - - /** - * For any node that {@link #isInstrumentable()}, this method must return a {@link Node} that: - *

    - *
  1. implements {@link WrapperNode}
  2. - *
  3. has {@code this} as it's child, and
  4. - *
  5. whose type is safe for replacement of {@code this} in the parent.
  6. - *
- * - * @return an appropriately typed {@link WrapperNode} if {@link #isInstrumentable()}. - */ - public WrapperNode createWrapperNode() { - return null; - } - - /** - * Enables {@linkplain Instrument instrumentation} of a node, where the node is presumed to be - * part of a well-formed Truffle AST that is not being executed. If this node has not already - * been probed, modifies the AST by inserting a {@linkplain WrapperNode wrapper node} between - * the node and its parent; the wrapper node must be provided by implementations of - * {@link #createWrapperNode()}. No more than one {@link Probe} may be associated with a node, - * so a {@linkplain WrapperNode wrapper} may not wrap another {@linkplain WrapperNode wrapper}. - * - * @return a (possibly newly created) {@link Probe} associated with this node. - * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged - */ - public final Probe probe() { - - if (this instanceof WrapperNode) { - throw new ProbeException(ProbeFailure.Reason.WRAPPER_NODE, null, this, null); - } - - if (parent == null) { - throw new ProbeException(ProbeFailure.Reason.NO_PARENT, null, this, null); - } - - if (parent instanceof WrapperNode) { - return ((WrapperNode) parent).getProbe(); - } - - if (!isInstrumentable()) { - throw new ProbeException(ProbeFailure.Reason.NOT_INSTRUMENTABLE, parent, this, null); - } - - // Create a new wrapper/probe with this node as its child. - final WrapperNode wrapper = createWrapperNode(); - - if (wrapper == null || !(wrapper instanceof Node)) { - throw new ProbeException(ProbeFailure.Reason.NO_WRAPPER, parent, this, wrapper); - } - - final Node wrapperNode = (Node) wrapper; - - if (!this.isSafelyReplaceableBy(wrapperNode)) { - throw new ProbeException(ProbeFailure.Reason.WRAPPER_TYPE, parent, this, wrapper); - } - - // Connect it to a Probe - final Probe probe = ProbeNode.insertProbe(wrapper); - - // Replace this node in the AST with the wrapper - this.replace(wrapperNode); - - return probe; - } - - /** - * Converts this node to a textual representation useful for debugging. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(getClass().getSimpleName()); - Map properties = getDebugProperties(); - boolean hasProperties = false; - for (Map.Entry entry : properties.entrySet()) { - sb.append(hasProperties ? "," : "<"); - hasProperties = true; - sb.append(entry.getKey()).append("=").append(entry.getValue()); - } - if (hasProperties) { - sb.append(">"); - } - sb.append("@").append(Integer.toHexString(hashCode())); - return sb.toString(); - } - - public final void atomic(Runnable closure) { - RootNode rootNode = getRootNode(); - synchronized (rootNode != null ? rootNode : GIL) { - assert enterAtomic(); - try { - closure.run(); - } finally { - assert exitAtomic(); - } - } - } - - public final T atomic(Callable closure) { - try { - RootNode rootNode = getRootNode(); - synchronized (rootNode != null ? rootNode : GIL) { - assert enterAtomic(); - try { - return closure.call(); - } finally { - assert exitAtomic(); - } - } - } catch (RuntimeException | Error e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Returns a user-readable description of the purpose of the Node, or "" if no description is - * available. - */ - public String getDescription() { - NodeInfo info = getClass().getAnnotation(NodeInfo.class); - if (info != null) { - return info.description(); - } - return ""; - } - - /** - * Returns a string representing the language this node has been implemented for. If the - * language is unknown, returns "". - */ - public String getLanguage() { - NodeInfo info = getClass().getAnnotation(NodeInfo.class); - if (info != null && info.language() != null && info.language().length() > 0) { - return info.language(); - } - if (parent != null) { - return parent.getLanguage(); - } - return ""; - } - - private static final Object GIL = new Object(); - - private static final ThreadLocal IN_ATOMIC_BLOCK = new ThreadLocal() { - @Override - protected Integer initialValue() { - return 0; - } - }; - - private static boolean inAtomicBlock() { - return IN_ATOMIC_BLOCK.get() > 0; - } - - private static boolean enterAtomic() { - IN_ATOMIC_BLOCK.set(IN_ATOMIC_BLOCK.get() + 1); - return true; - } - - private static boolean exitAtomic() { - IN_ATOMIC_BLOCK.set(IN_ATOMIC_BLOCK.get() - 1); - return true; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.lang.reflect.*; -import java.security.*; -import java.util.*; - -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; - -/** - * Information about a {@link Node} class. A single instance of this class is allocated for every - * subclass of {@link Node} that is used. - */ -public final class NodeClass { - private static final ClassValue nodeClasses = new ClassValue() { - @SuppressWarnings("unchecked") - @Override - protected NodeClass computeValue(final Class clazz) { - assert Node.class.isAssignableFrom(clazz); - return AccessController.doPrivileged(new PrivilegedAction() { - public NodeClass run() { - return new NodeClass((Class) clazz); - } - }); - } - }; - - // The comprehensive list of all fields. - private final NodeFieldAccessor[] fields; - // Separate arrays for the frequently accessed fields. - private final NodeFieldAccessor parentField; - private final NodeFieldAccessor nodeClassField; - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; - private final NodeFieldAccessor[] cloneableFields; - - private final Class clazz; - - public static NodeClass get(Class clazz) { - return nodeClasses.get(clazz); - } - - public static NodeClass get(Node clazz) { - return clazz.getNodeClass(); - } - - public NodeClass(Class clazz) { - List fieldsList = new ArrayList<>(); - NodeFieldAccessor parentFieldTmp = null; - NodeFieldAccessor nodeClassFieldTmp = null; - List childFieldList = new ArrayList<>(); - List childrenFieldList = new ArrayList<>(); - List cloneableFieldList = new ArrayList<>(); - - for (Field field : NodeUtil.getAllFields(clazz)) { - if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { - continue; - } - - NodeFieldAccessor nodeField; - if (field.getDeclaringClass() == Node.class && field.getName().equals("parent")) { - assert Node.class.isAssignableFrom(field.getType()); - nodeField = NodeFieldAccessor.create(NodeFieldKind.PARENT, field); - parentFieldTmp = nodeField; - } else if (field.getDeclaringClass() == Node.class && field.getName().equals("nodeClass")) { - assert NodeClass.class.isAssignableFrom(field.getType()); - nodeField = NodeFieldAccessor.create(NodeFieldKind.NODE_CLASS, field); - nodeClassFieldTmp = nodeField; - } else if (field.getAnnotation(Child.class) != null) { - checkChildField(field); - nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILD, field); - childFieldList.add(nodeField); - } else if (field.getAnnotation(Children.class) != null) { - checkChildrenField(field); - nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILDREN, field); - childrenFieldList.add(nodeField); - } else { - nodeField = NodeFieldAccessor.create(NodeFieldKind.DATA, field); - if (NodeCloneable.class.isAssignableFrom(field.getType())) { - cloneableFieldList.add(nodeField); - } - } - fieldsList.add(nodeField); - } - - if (parentFieldTmp == null) { - throw new AssertionError("parent field not found"); - } - - this.fields = fieldsList.toArray(new NodeFieldAccessor[fieldsList.size()]); - this.nodeClassField = nodeClassFieldTmp; - this.parentField = parentFieldTmp; - this.childFields = childFieldList.toArray(new NodeFieldAccessor[childFieldList.size()]); - this.childrenFields = childrenFieldList.toArray(new NodeFieldAccessor[childrenFieldList.size()]); - this.cloneableFields = cloneableFieldList.toArray(new NodeFieldAccessor[cloneableFieldList.size()]); - this.clazz = clazz; - } - - public NodeFieldAccessor getNodeClassField() { - return nodeClassField; - } - - public NodeFieldAccessor[] getCloneableFields() { - return cloneableFields; - } - - private static boolean isNodeType(Class clazz) { - return Node.class.isAssignableFrom(clazz) || (clazz.isInterface() && NodeInterface.class.isAssignableFrom(clazz)); - } - - private static void checkChildField(Field field) { - if (!isNodeType(field.getType())) { - throw new AssertionError("@Child field type must be a subclass of Node or an interface extending NodeInterface (" + field + ")"); - } - if (Modifier.isFinal(field.getModifiers())) { - throw new AssertionError("@Child field must not be final (" + field + ")"); - } - } - - private static void checkChildrenField(Field field) { - if (!(field.getType().isArray() && isNodeType(field.getType().getComponentType()))) { - throw new AssertionError("@Children field type must be an array of a subclass of Node or an interface extending NodeInterface (" + field + ")"); - } - if (!Modifier.isFinal(field.getModifiers())) { - throw new AssertionError("@Children field must be final (" + field + ")"); - } - } - - public NodeFieldAccessor[] getFields() { - return fields; - } - - public NodeFieldAccessor getParentField() { - return parentField; - } - - public NodeFieldAccessor[] getChildFields() { - return childFields; - } - - public NodeFieldAccessor[] getChildrenFields() { - return childrenFields; - } - - @Override - public int hashCode() { - return clazz.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof NodeClass) { - NodeClass other = (NodeClass) obj; - return clazz.equals(other.clazz); - } - return false; - } - - public Iterator makeIterator(Node node) { - assert clazz.isInstance(node); - return new NodeIterator(this, node); - } - - private static final class NodeIterator implements Iterator { - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; - private final Node node; - private final int childrenCount; - private int index; - - protected NodeIterator(NodeClass nodeClass, Node node) { - this.childFields = nodeClass.getChildFields(); - this.childrenFields = nodeClass.getChildrenFields(); - this.node = node; - this.childrenCount = childrenCount(); - this.index = 0; - } - - private int childrenCount() { - int nodeCount = childFields.length; - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] children = ((Object[]) childrenField.getObject(node)); - if (children != null) { - nodeCount += children.length; - } - } - return nodeCount; - } - - private Node nodeAt(int idx) { - int nodeCount = childFields.length; - if (idx < nodeCount) { - return (Node) childFields[idx].getObject(node); - } else { - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] nodeArray = (Object[]) childrenField.getObject(node); - if (idx < nodeCount + nodeArray.length) { - return (Node) nodeArray[idx - nodeCount]; - } - nodeCount += nodeArray.length; - } - } - return null; - } - - private void forward() { - if (index < childrenCount) { - index++; - } - } - - public boolean hasNext() { - return index < childrenCount; - } - - public Node next() { - try { - return nodeAt(index); - } finally { - forward(); - } - } - - public void remove() { - throw new UnsupportedOperationException(); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCloneable.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCloneable.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Declarative base class for node fields that are to be cloned together with the containing node. - */ -public abstract class NodeCloneable implements Cloneable { - @Override - protected Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; - -/** - * Represents a rough estimate for the cost of a {@link Node}. This estimate can be used by runtime - * systems or guest languages to implement heuristics based on Truffle ASTs. - * - * @see Node#getCost() - */ -public enum NodeCost { - - /** - * This node has literally no costs and should be ignored for heuristics. This is particularly - * useful for wrapper and profiling nodes which should not influence the heuristics. - */ - NONE, - - /** - * This node has a {@link CompilerDirectives#transferToInterpreter()} or - * {@link CompilerDirectives#transferToInterpreterAndInvalidate()} as its first unconditional - * statement. - */ - UNINITIALIZED, - - /** - * This node represents a specialized monomorphic version of an operation. - */ - MONOMORPHIC, - - /** - * This node represents a polymorphic version of an operation. For multiple chained polymorphic - * nodes the first may return {@link #MONOMORPHIC} and all additional nodes should return - * {@link #POLYMORPHIC}. - */ - POLYMORPHIC, - - /** - * This node represents a megamorphic version of an operation. This value should only be used if - * the operation implementation supports monomorphism and polymorphism otherwise - * {@link #MONOMORPHIC} should be used instead. - */ - MEGAMORPHIC; - - public boolean isTrivial() { - return this == NONE || this == UNINITIALIZED; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.lang.reflect.*; - -import sun.misc.*; - -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.nodes.NodeUtil.FieldOffsetProvider; - -/** - * Information about a field in a {@link Node} class. - */ -public abstract class NodeFieldAccessor { - - public static enum NodeFieldKind { - /** The reference to the {@link NodeClass}. */ - NODE_CLASS, - /** The single {@link Node#getParent() parent} field. */ - PARENT, - /** A field annotated with {@link Child}. */ - CHILD, - /** A field annotated with {@link Children}. */ - CHILDREN, - /** A normal non-child data field of the node. */ - DATA - } - - private static final boolean USE_UNSAFE = Boolean.getBoolean("truffle.unsafe"); - - private final NodeFieldKind kind; - private final String name; - protected final Class type; - protected final long offset; - - protected NodeFieldAccessor(NodeFieldKind kind, Field field) { - this.kind = kind; - this.type = field.getType(); - this.name = field.getName(); - this.offset = unsafeFieldOffsetProvider.objectFieldOffset(field); - } - - protected static NodeFieldAccessor create(NodeFieldKind kind, Field field) { - if (USE_UNSAFE) { - return new UnsafeNodeField(kind, field); - } else { - return new ReflectionNodeField(kind, field); - } - } - - public NodeFieldKind getKind() { - return kind; - } - - public Class getType() { - return type; - } - - public String getName() { - return name; - } - - public long getOffset() { - return offset; - } - - public abstract void putObject(Node receiver, Object value); - - public abstract Object getObject(Node receiver); - - public abstract Object loadValue(Node node); - - @Override - public int hashCode() { - return kind.hashCode() | type.hashCode() | name.hashCode() | ((Long) offset).hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof NodeFieldAccessor) { - NodeFieldAccessor other = (NodeFieldAccessor) obj; - return offset == other.offset && name.equals(other.name) && type.equals(other.type) && kind.equals(other.kind); - } - return false; - } - - private static final Unsafe unsafe = getUnsafe(); - - private static Unsafe getUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException e) { - } - try { - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeInstance.setAccessible(true); - return (Unsafe) theUnsafeInstance.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); - } - } - - private static final FieldOffsetProvider unsafeFieldOffsetProvider = new FieldOffsetProvider() { - - @Override - public long objectFieldOffset(Field field) { - return unsafe.objectFieldOffset(field); - } - - @Override - public int getTypeSize(Class clazz) { - if (!clazz.isPrimitive()) { - return Unsafe.ARRAY_OBJECT_INDEX_SCALE; - } else if (clazz == int.class) { - return Unsafe.ARRAY_INT_INDEX_SCALE; - } else { - throw new UnsupportedOperationException("unsupported field type: " + clazz); - } - } - }; - - private static final class UnsafeNodeField extends NodeFieldAccessor { - - protected UnsafeNodeField(NodeFieldKind kind, Field field) { - super(kind, field); - } - - @Override - public void putObject(Node receiver, Object value) { - if (!type.isPrimitive() && value == null || type.isInstance(value)) { - unsafe.putObject(receiver, offset, value); - } else { - throw new IllegalArgumentException(); - } - } - - @Override - public Object getObject(Node receiver) { - if (!type.isPrimitive()) { - return unsafe.getObject(receiver, offset); - } else { - throw new IllegalArgumentException(); - } - } - - @Override - public Object loadValue(Node node) { - if (type == boolean.class) { - return unsafe.getBoolean(node, offset); - } else if (type == byte.class) { - return unsafe.getByte(node, offset); - } else if (type == short.class) { - return unsafe.getShort(node, offset); - } else if (type == char.class) { - return unsafe.getChar(node, offset); - } else if (type == int.class) { - return unsafe.getInt(node, offset); - } else if (type == long.class) { - return unsafe.getLong(node, offset); - } else if (type == float.class) { - return unsafe.getFloat(node, offset); - } else if (type == double.class) { - return unsafe.getDouble(node, offset); - } else { - return unsafe.getObject(node, offset); - } - } - } - - private static final class ReflectionNodeField extends NodeFieldAccessor { - private final Field field; - - protected ReflectionNodeField(NodeFieldKind kind, Field field) { - super(kind, field); - this.field = field; - field.setAccessible(true); - } - - @Override - public void putObject(Node receiver, Object value) { - assert !type.isPrimitive() && value == null || type.isInstance(value); - try { - field.set(receiver, value); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - - @Override - public Object getObject(Node receiver) { - assert !type.isPrimitive(); - try { - return field.get(receiver); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - - @Override - public Object loadValue(Node node) { - try { - if (type == boolean.class) { - return field.getBoolean(node); - } else if (type == byte.class) { - return field.getByte(node); - } else if (type == short.class) { - return field.getShort(node); - } else if (type == char.class) { - return field.getChar(node); - } else if (type == int.class) { - return field.getInt(node); - } else if (type == long.class) { - return field.getLong(node); - } else if (type == float.class) { - return field.getFloat(node); - } else if (type == double.class) { - return field.getDouble(node); - } else { - return field.get(node); - } - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.lang.annotation.*; - -/** - * Annotation for providing additional information on nodes. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface NodeInfo { - - /** - * Short name representing the node that can be used for debugging. - * - * @return the short name - */ - String shortName() default ""; - - /** - * Provides a rough estimate for the cost of the annotated {@link Node}. This estimate can be - * used by runtime systems or guest languages to implement heuristics based on Truffle ASTs. - * - * @see Node#getCost() - * @see NodeCost - */ - NodeCost cost() default NodeCost.MONOMORPHIC; - - /** - * A human readable explanation of the purpose of the annotated {@link Node}. Can be used e.g. - * for debugging or visualization purposes. - * - * @return the description - */ - String description() default ""; - - /** - * A description, providing a user-readable explanation of the source language of the annotated - * {@link Node}. Can be used e.g. for debugging or visualization purposes. Typically this - * information is set only in an abstract base node for the language implementation. - * - * @return the description - */ - String language() default ""; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInterface.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInterface.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Common base interface for all Truffle nodes. - * - * @see Node - */ -public interface NodeInterface { -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,841 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.io.*; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.util.*; - -import sun.misc.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; -import com.oracle.truffle.api.source.*; - -/** - * Utility class that manages the special access methods for node instances. - */ -public final class NodeUtil { - - /** - * Interface that allows the customization of field offsets used for {@link Unsafe} field - * accesses. - */ - public interface FieldOffsetProvider { - - long objectFieldOffset(Field field); - - int getTypeSize(Class clazz); - } - - static Iterator makeIterator(Node node) { - return node.getNodeClass().makeIterator(node); - } - - public static Iterator makeRecursiveIterator(Node node) { - return new RecursiveNodeIterator(node); - } - - private static final class RecursiveNodeIterator implements Iterator { - private final List> iteratorStack = new ArrayList<>(); - - public RecursiveNodeIterator(final Node node) { - iteratorStack.add(new Iterator() { - - private boolean visited; - - public void remove() { - throw new UnsupportedOperationException(); - } - - public Node next() { - if (visited) { - throw new NoSuchElementException(); - } - visited = true; - return node; - } - - public boolean hasNext() { - return !visited; - } - }); - } - - public boolean hasNext() { - return peekIterator() != null; - } - - public Node next() { - Iterator iterator = peekIterator(); - if (iterator == null) { - throw new NoSuchElementException(); - } - - Node node = iterator.next(); - if (node != null) { - Iterator childIterator = makeIterator(node); - if (childIterator.hasNext()) { - iteratorStack.add(childIterator); - } - } - return node; - } - - private Iterator peekIterator() { - int tos = iteratorStack.size() - 1; - while (tos >= 0) { - Iterator iterable = iteratorStack.get(tos); - if (iterable.hasNext()) { - return iterable; - } else { - iteratorStack.remove(tos--); - } - } - return null; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - } - - @SuppressWarnings("unchecked") - public static T cloneNode(T orig) { - return (T) orig.deepCopy(); - } - - static Node deepCopyImpl(Node orig) { - final Node clone = orig.copy(); - NodeClass nodeClass = clone.getNodeClass(); - - nodeClass.getParentField().putObject(clone, null); - - for (NodeFieldAccessor childField : nodeClass.getChildFields()) { - Node child = (Node) childField.getObject(orig); - if (child != null) { - Node clonedChild = child.deepCopy(); - nodeClass.getParentField().putObject(clonedChild, clone); - childField.putObject(clone, clonedChild); - } - } - for (NodeFieldAccessor childrenField : nodeClass.getChildrenFields()) { - Object[] children = (Object[]) childrenField.getObject(orig); - if (children != null) { - Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); - for (int i = 0; i < children.length; i++) { - if (children[i] != null) { - Node clonedChild = ((Node) children[i]).deepCopy(); - clonedChildren[i] = clonedChild; - nodeClass.getParentField().putObject(clonedChild, clone); - } - } - childrenField.putObject(clone, clonedChildren); - } - } - for (NodeFieldAccessor cloneableField : nodeClass.getCloneableFields()) { - Object cloneable = cloneableField.getObject(clone); - if (cloneable != null && cloneable == cloneableField.getObject(orig)) { - cloneableField.putObject(clone, ((NodeCloneable) cloneable).clone()); - } - } - return clone; - } - - public static List findNodeChildren(Node node) { - List nodes = new ArrayList<>(); - NodeClass nodeClass = node.getNodeClass(); - - for (NodeFieldAccessor nodeField : nodeClass.getChildFields()) { - Object child = nodeField.getObject(node); - if (child != null) { - nodes.add((Node) child); - } - } - for (NodeFieldAccessor nodeField : nodeClass.getChildrenFields()) { - Object[] children = (Object[]) nodeField.getObject(node); - if (children != null) { - for (Object child : children) { - if (child != null) { - nodes.add((Node) child); - } - } - } - } - - return nodes; - } - - public static T nonAtomicReplace(Node oldNode, T newNode, CharSequence reason) { - oldNode.replaceHelper(newNode, reason); - return newNode; - } - - public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { - NodeClass nodeClass = parent.getNodeClass(); - - for (NodeFieldAccessor nodeField : nodeClass.getChildFields()) { - if (nodeField.getObject(parent) == oldChild) { - assert assertAssignable(nodeField, newChild); - nodeField.putObject(parent, newChild); - return true; - } - } - - for (NodeFieldAccessor nodeField : nodeClass.getChildrenFields()) { - Object arrayObject = nodeField.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (array[i] == oldChild) { - assert assertAssignable(nodeField, newChild); - array[i] = newChild; - return true; - } - } - } - } - return false; - } - - private static boolean assertAssignable(NodeFieldAccessor field, Object newValue) { - if (newValue == null) { - return true; - } - if (field.getKind() == NodeFieldKind.CHILD) { - if (field.getType().isAssignableFrom(newValue.getClass())) { - return true; - } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); - return false; - } - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { - return true; - } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); - return false; - } - } - throw new IllegalArgumentException(); - } - - /** - * Finds the field in a parent node, if any, that holds a specified child node. - * - * @return the field (possibly an array) holding the child, {@code null} if not found. - */ - public static NodeFieldAccessor findChildField(Node parent, Node child) { - assert child != null; - NodeClass parentNodeClass = parent.getNodeClass(); - - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - if (field.getObject(parent) == child) { - return field; - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (array[i] == child) { - return field; - } - } - } - } - return null; - } - - /** - * Determines whether a proposed child replacement would be safe: structurally and type. - */ - public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChild) { - assert newChild != null; - if (parent != null) { - final NodeFieldAccessor field = findChildField(parent, oldChild); - if (field != null) { - switch (field.getKind()) { - case CHILD: - return field.getType().isAssignableFrom(newChild.getClass()); - case CHILDREN: - return field.getType().getComponentType().isAssignableFrom(newChild.getClass()); - default: - throw new IllegalStateException(); - } - } - } - return false; - } - - /** - * Executes a closure for every non-null child of the parent node. - * - * @return {@code true} if all children were visited, {@code false} otherwise - */ - public static boolean forEachChild(Node parent, NodeVisitor visitor) { - Objects.requireNonNull(visitor); - NodeClass parentNodeClass = parent.getNodeClass(); - - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - Object child = field.getObject(parent); - if (child != null) { - if (!visitor.visit((Node) child)) { - return false; - } - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - Object child = array[i]; - if (child != null) { - if (!visitor.visit((Node) child)) { - return false; - } - } - } - } - } - - return true; - } - - static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { - NodeClass parentNodeClass = parent.getNodeClass(); - - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - if (!visitChild((Node) field.getObject(parent), visitor)) { - return false; - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject == null) { - continue; - } - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (!visitChild((Node) array[i], visitor)) { - return false; - } - } - } - - return true; - } - - private static boolean visitChild(Node child, NodeVisitor visitor) { - if (child == null) { - return true; - } - if (!visitor.visit(child)) { - return false; - } - if (!forEachChildRecursive(child, visitor)) { - return false; - } - return true; - } - - /** Returns all declared fields in the class hierarchy. */ - static Field[] getAllFields(Class clazz) { - Field[] declaredFields = clazz.getDeclaredFields(); - if (clazz.getSuperclass() != null) { - return concat(getAllFields(clazz.getSuperclass()), declaredFields); - } - return declaredFields; - } - - public static T[] concat(T[] first, T[] second) { - T[] result = Arrays.copyOf(first, first.length + second.length); - System.arraycopy(second, 0, result, first.length, second.length); - return result; - } - - /** - * Get the nth parent of a node, where the 0th parent is the node itself. Returns null if there - * are less than n ancestors. - */ - public static Node getNthParent(Node node, int n) { - Node parent = node; - - for (int i = 0; i < n; i++) { - parent = parent.getParent(); - - if (parent == null) { - return null; - } - } - - return parent; - } - - /** find annotation in class/interface hierarchy. */ - public static T findAnnotation(Class clazz, Class annotationClass) { - if (clazz.getAnnotation(annotationClass) != null) { - return clazz.getAnnotation(annotationClass); - } else { - for (Class intf : clazz.getInterfaces()) { - if (intf.getAnnotation(annotationClass) != null) { - return intf.getAnnotation(annotationClass); - } - } - if (clazz.getSuperclass() != null) { - return findAnnotation(clazz.getSuperclass(), annotationClass); - } - } - return null; - } - - public static T findParent(Node start, Class clazz) { - Node parent = start.getParent(); - if (parent == null) { - return null; - } else if (clazz.isInstance(parent)) { - return clazz.cast(parent); - } else { - return findParent(parent, clazz); - } - } - - public static List findAllParents(Node start, Class clazz) { - List parents = new ArrayList<>(); - T parent = findParent(start, clazz); - while (parent != null) { - parents.add(parent); - parent = findParent((Node) parent, clazz); - } - return parents; - } - - public static List collectNodes(Node parent, Node child) { - List nodes = new ArrayList<>(); - Node current = child; - while (current != null) { - nodes.add(current); - if (current == parent) { - return nodes; - } - current = current.getParent(); - } - throw new IllegalArgumentException("Node " + parent + " is not a parent of " + child + "."); - } - - public static T findFirstNodeInstance(Node root, Class clazz) { - if (clazz.isInstance(root)) { - return clazz.cast(root); - } - for (Node child : root.getChildren()) { - T node = findFirstNodeInstance(child, clazz); - if (node != null) { - return node; - } - } - return null; - } - - public static List findAllNodeInstances(final Node root, final Class clazz) { - final List nodeList = new ArrayList<>(); - root.accept(new NodeVisitor() { - public boolean visit(Node node) { - if (clazz.isInstance(node)) { - nodeList.add(clazz.cast(node)); - } - return true; - } - }); - return nodeList; - } - - public static int countNodes(Node root) { - return countNodes(root, NodeCountFilter.NO_FILTER); - } - - public static int countNodes(Node root, NodeCountFilter filter) { - NodeCounter counter = new NodeCounter(filter); - root.accept(counter); - return counter.count; - } - - public interface NodeCountFilter { - - NodeCountFilter NO_FILTER = new NodeCountFilter() { - - public boolean isCounted(Node node) { - return true; - } - }; - - boolean isCounted(Node node); - - } - - public static String printCompactTreeToString(Node node) { - StringWriter out = new StringWriter(); - printCompactTree(new PrintWriter(out), null, node, 1); - return out.toString(); - } - - public static void printCompactTree(OutputStream out, Node node) { - printCompactTree(new PrintWriter(out), null, node, 1); - } - - private static void printCompactTree(PrintWriter p, Node parent, Node node, int level) { - if (node == null) { - return; - } - for (int i = 0; i < level; i++) { - p.print(" "); - } - if (parent == null) { - p.println(nodeName(node)); - } else { - p.print(getNodeFieldName(parent, node, "unknownField")); - p.print(" = "); - p.println(nodeName(node)); - } - - for (Node child : node.getChildren()) { - printCompactTree(p, node, child, level + 1); - } - p.flush(); - } - - public static String printSourceAttributionTree(Node node) { - StringWriter out = new StringWriter(); - printSourceAttributionTree(new PrintWriter(out), null, node, 1); - return out.toString(); - } - - public static void printSourceAttributionTree(OutputStream out, Node node) { - printSourceAttributionTree(new PrintWriter(out), null, node, 1); - } - - public static void printSourceAttributionTree(PrintWriter out, Node node) { - printSourceAttributionTree(out, null, node, 1); - } - - private static void printSourceAttributionTree(PrintWriter p, Node parent, Node node, int level) { - if (node == null) { - return; - } - if (parent == null) { - // Add some preliminary information before starting with the root node - final SourceSection sourceSection = node.getSourceSection(); - if (sourceSection != null) { - final String txt = sourceSection.getSource().getCode(); - p.println("Full source len=(" + txt.length() + ") ___" + txt + "___"); - p.println("AST source attribution:"); - } - } - final StringBuilder sb = new StringBuilder(); - for (int i = 0; i < level; i++) { - sb.append("| "); - } - - if (parent != null) { - sb.append(getNodeFieldName(parent, node, "")); - } - - sb.append(" (" + node.getClass().getSimpleName() + ") "); - - sb.append(printSyntaxTags(node)); - - sb.append(displaySourceAttribution(node)); - p.println(sb.toString()); - - for (Node child : node.getChildren()) { - printSourceAttributionTree(p, node, child, level + 1); - } - p.flush(); - } - - private static String getNodeFieldName(Node parent, Node node, String defaultName) { - NodeFieldAccessor[] fields = parent.getNodeClass().getFields(); - for (NodeFieldAccessor field : fields) { - Object value = field.loadValue(parent); - if (field.getKind() == NodeFieldKind.CHILD && value == node) { - return field.getName(); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - int index = 0; - for (Object arrayNode : (Object[]) value) { - if (arrayNode == node) { - return field.getName() + "[" + index + "]"; - } - index++; - } - } - } - return defaultName; - } - - /** - * Returns a string listing the {@linkplain SyntaxTag syntax tags}, if any, associated with a - * node: - *
    - *
  • "[{@linkplain StandardSyntaxTag#STATEMENT STATEMENT}, - * {@linkplain StandardSyntaxTag#ASSIGNMENT ASSIGNMENT}]" if tags have been applied;
  • - *
  • "[]" if the node supports tags, but none are present; and
  • - *
  • "" if the node does not support tags.
  • - *
- */ - public static String printSyntaxTags(final Object node) { - if (node instanceof WrapperNode) { - final Probe probe = ((WrapperNode) node).getProbe(); - final Collection syntaxTags = probe.getSyntaxTags(); - final StringBuilder sb = new StringBuilder(); - String prefix = ""; - sb.append("["); - for (SyntaxTag tag : syntaxTags) { - sb.append(prefix); - prefix = ","; - sb.append(tag.toString()); - } - sb.append("]"); - return sb.toString(); - } - return ""; - } - - /** - * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This - * print method does not check for cycles in the node structure. - * - * @param out the stream to print to. - * @param node the root node to write - */ - public static void printTree(OutputStream out, Node node) { - printTree(new PrintWriter(out), node); - } - - public static String printTreeToString(Node node) { - StringWriter out = new StringWriter(); - printTree(new PrintWriter(out), node); - return out.toString(); - } - - public static void printTree(PrintWriter p, Node node) { - printTree(p, node, 1); - p.println(); - p.flush(); - } - - private static void printTree(PrintWriter p, Node node, int level) { - if (node == null) { - p.print("null"); - return; - } - - p.print(nodeName(node)); - - ArrayList childFields = new ArrayList<>(); - String sep = ""; - p.print("("); - for (NodeFieldAccessor field : NodeClass.get(node).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { - childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { - p.print(sep); - sep = ", "; - - p.print(field.getName()); - p.print(" = "); - p.print(field.loadValue(node)); - } - } - p.print(")"); - - if (childFields.size() != 0) { - p.print(" {"); - for (NodeFieldAccessor field : childFields) { - printNewLine(p, level); - p.print(field.getName()); - - Object value = field.loadValue(node); - if (value == null) { - p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { - p.print(" = "); - printTree(p, (Node) value, level + 1); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - printChildren(p, level, value); - } - } - printNewLine(p, level - 1); - p.print("}"); - } - } - - private static void printChildren(PrintWriter p, int level, Object value) { - String sep; - Object[] children = (Object[]) value; - p.print(" = ["); - sep = ""; - for (Object child : children) { - p.print(sep); - sep = ", "; - printTree(p, (Node) child, level + 1); - } - p.print("]"); - } - - private static void printNewLine(PrintWriter p, int level) { - p.println(); - for (int i = 0; i < level; i++) { - p.print(" "); - } - } - - private static String nodeName(Node node) { - return node.getClass().getSimpleName(); - } - - private static String displaySourceAttribution(Node node) { - final SourceSection section = node.getSourceSection(); - if (section instanceof NullSourceSection) { - return "source: " + section.getShortDescription(); - } - if (section != null) { - final String srcText = section.getCode(); - final StringBuilder sb = new StringBuilder(); - sb.append("source:"); - sb.append(" (" + section.getCharIndex() + "," + (section.getCharEndIndex() - 1) + ")"); - sb.append(" line=" + section.getLineLocation().getLineNumber()); - sb.append(" len=" + srcText.length()); - sb.append(" text=\"" + srcText + "\""); - return sb.toString(); - } - return ""; - } - - public static boolean verify(Node root) { - Iterable children = root.getChildren(); - for (Node child : children) { - if (child != null) { - if (child.getParent() != root) { - throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root)); - } - verify(child); - } - } - return true; - } - - private static String toStringWithClass(Object obj) { - return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")"; - } - - static void traceRewrite(Node oldNode, Node newNode, CharSequence reason) { - if (TruffleOptions.TraceRewritesFilterFromCost != null) { - if (filterByKind(oldNode, TruffleOptions.TraceRewritesFilterFromCost)) { - return; - } - } - - if (TruffleOptions.TraceRewritesFilterToCost != null) { - if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { - return; - } - } - - String filter = TruffleOptions.TraceRewritesFilterClass; - Class from = oldNode.getClass(); - Class to = newNode.getClass(); - if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { - return; - } - - final SourceSection reportedSourceSection = oldNode.getEncapsulatingSourceSection(); - - PrintStream out = System.out; - out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", oldNode.toString(), formatNodeInfo(oldNode), formatNodeInfo(newNode), - reason != null && reason.length() > 0 ? reason : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); - } - - private static String formatNodeInfo(Node node) { - String cost = "?"; - switch (node.getCost()) { - case NONE: - cost = "G"; - break; - case MONOMORPHIC: - cost = "M"; - break; - case POLYMORPHIC: - cost = "P"; - break; - case MEGAMORPHIC: - cost = "G"; - break; - default: - cost = "?"; - break; - } - return cost + " " + node.getClass().getSimpleName(); - } - - private static boolean filterByKind(Node node, NodeCost cost) { - return node.getCost() == cost; - } - - private static boolean filterByContainsClassName(Class from, String filter) { - Class currentFrom = from; - while (currentFrom != null) { - if (currentFrom.getName().contains(filter)) { - return false; - } - currentFrom = currentFrom.getSuperclass(); - } - return true; - } - - private static final class NodeCounter implements NodeVisitor { - - public int count; - private final NodeCountFilter filter; - - public NodeCounter(NodeCountFilter filter) { - this.filter = filter; - } - - public boolean visit(Node node) { - if (filter.isCounted(node)) { - count++; - } - return true; - } - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Visitor for trees of nodes. - */ -public interface NodeVisitor { - - /** - * This visitor method is called for every node in the tree. Its return value determines if the - * children of this node should be excluded in the iteration. - * - * @param node the node that is currently visited - * @return {@code true} if the children should be visited too, {@code false} otherwise - */ - boolean visit(Node node); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RepeatingNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RepeatingNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.frame.*; - -/** - * Experimental API: may change significantly without notice. - */ -public interface RepeatingNode extends NodeInterface { - - boolean executeRepeating(VirtualFrame frame); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -/** - * A root node is a node with a method to execute it given only a frame as a parameter. Therefore, a - * root node can be used to create a call target using - * {@link TruffleRuntime#createCallTarget(RootNode)}. - */ -public abstract class RootNode extends Node { - - private RootCallTarget callTarget; - @CompilationFinal private FrameDescriptor frameDescriptor; - - protected RootNode() { - this(null, null); - } - - protected RootNode(SourceSection sourceSection) { - this(sourceSection, null); - } - - protected RootNode(SourceSection sourceSection, FrameDescriptor frameDescriptor) { - super(sourceSection); - if (frameDescriptor == null) { - this.frameDescriptor = new FrameDescriptor(); - } else { - this.frameDescriptor = frameDescriptor; - } - } - - @Override - public Node copy() { - RootNode root = (RootNode) super.copy(); - root.frameDescriptor = frameDescriptor; - return root; - } - - /** - * Returns true if this {@link RootNode} is allowed to be cloned. The runtime - * system might decide to create deep copies of the {@link RootNode} in order to gather context - * sensitive profiling feedback. The default implementation returns false. Guest - * language specific implementations may want to return true here to indicate that - * gathering call site specific profiling information might make sense for this {@link RootNode} - * . - * - * @return true if cloning is allowed else false. - */ - public boolean isCloningAllowed() { - return false; - } - - /** - * Reports the execution count of a loop that is a child of this node. The optimization - * heuristics can use the loop count to guide compilation and inlining. - */ - public final void reportLoopCount(int count) { - if (getCallTarget() instanceof LoopCountReceiver) { - ((LoopCountReceiver) getCallTarget()).reportLoopCount(count); - } - } - - /** - * Executes this function using the specified frame and returns the result value. - * - * @param frame the frame of the currently executing guest language method - * @return the value of the execution - */ - public abstract Object execute(VirtualFrame frame); - - public final RootCallTarget getCallTarget() { - return callTarget; - } - - public final FrameDescriptor getFrameDescriptor() { - return frameDescriptor; - } - - public final void setCallTarget(RootCallTarget callTarget) { - this.callTarget = callTarget; - } - - /** - * Returns the {@link ExecutionContext} associated with this RootNode. This allows - * the correct ExecutionContext to be determined for a RootNode (and - * so also for a {@link RootCallTarget} and a {@link FrameInstance} obtained from the call - * stack) without prior knowledge of the language it has come from. - * - * Used for instance to determine the language of a RootNode: - * - *
-     * 
-     * rootNode.getExecutionContext().getLanguageShortName();
-     *  
- * - * Returns null by default. - */ - public ExecutionContext getExecutionContext() { - return null; - } - - /** - * Get compiler options specific to this RootNode. - */ - public CompilerOptions getCompilerOptions() { - final ExecutionContext context = getExecutionContext(); - - if (context == null) { - return DefaultCompilerOptions.INSTANCE; - } else { - return context.getCompilerOptions(); - } - } - - /** - * Apply all registered instances of {@link ASTProber} to the AST, if any, held by this root - * node. This can only be done once the AST is complete, notably once all parent pointers are - * correctly assigned. But it also must be done before any AST cloning or execution. - *

- * If this is not done, then the AST will not be subject to debugging or any other - * instrumentation-supported tooling. - *

- * Implementations should ensure that instrumentation is never applied more than once to an AST, - * as this is not guaranteed to be error-free. - * - * @see Probe#registerASTProber(com.oracle.truffle.api.instrument.ASTProber) - */ - public void applyInstrumentation() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; - -/** - * An exception thrown to enter a slow path. The Truffle optimizer has special knowledge of this - * exception class and will never compile a catch block that catches this exception type. - */ -public class SlowPathException extends Exception { - - private static final long serialVersionUID = 3676602078425211386L; - - /** - * Creates an exception thrown to enter a slow path. - */ - public SlowPathException() { - CompilerDirectives.transferToInterpreter(); - } - - /** - * Creates an exception thrown to enter a slow path. - */ - public SlowPathException(String message, Throwable cause) { - super(message, cause); - CompilerDirectives.transferToInterpreter(); - } - - /** - * Creates an exception thrown to enter a slow path. - */ - public SlowPathException(String message) { - super(message); - CompilerDirectives.transferToInterpreter(); - } - - /** - * Creates an exception thrown to enter a slow path. - */ - public SlowPathException(Throwable cause) { - super(cause); - CompilerDirectives.transferToInterpreter(); - } - - /** - * For performance reasons, this exception does not record any stack trace information. - */ - @SuppressWarnings("sync-override") - @Override - public Throwable fillInStackTrace() { - return null; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; - -/** - * An exception that should be thrown if the return value cannot be represented as a value of the - * return type. The Truffle optimizer has special knowledge of this exception class and will never - * compile a catch block that catches this exception type. - */ -public final class UnexpectedResultException extends SlowPathException { - - private static final long serialVersionUID = 3676602078425211386L; - private final Object result; - - /** - * Creates the exception with the alternative result that cannot be represented as a value of - * the return type. - * - * @param result the alternative result - */ - public UnexpectedResultException(Object result) { - CompilerDirectives.transferToInterpreter(); - this.result = result; - } - - /** - * @return the unexpected result - */ - public Object getResult() { - return result; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/PostOrderDeserializer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/PostOrderDeserializer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,375 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.serial; - -import java.lang.reflect.*; -import java.util.*; - -import sun.misc.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; -import com.oracle.truffle.api.source.*; - -/** - * Experimental API. May change without notice. - */ -public final class PostOrderDeserializer { - - private static final Unsafe unsafe = loadUnsafe(); - - private final SerializerConstantPool cp; - - private final HierarchicalStack stack = new HierarchicalStack(); - - /** - * Constructs a new serializer using a custom {@link SerializerConstantPool} implementation. For - * the {@link SerializerConstantPool} implementation at least the following methods must be - * implemented: - *

    - *
  • {@link SerializerConstantPool#getInt(int)}
  • - *
  • {@link SerializerConstantPool#getClass(int)}
  • - *
- */ - public PostOrderDeserializer(SerializerConstantPool cp) { - this.cp = cp; - } - - /** - * Deserializes the byte stream and returns the deserialized Truffle AST node. - * - * @param bytes the trimmed byte array containing the serialized data - * @param expectedType the expected root node type. Throws an exception if the root node is not - * assignable from this type. - * @return the deserialized Truffle AST represented by the root Node. - * - * @throws UnsupportedConstantPoolTypeException thrown if a type is encountered that is not - * supported by the constant pool implementation. - */ - @SuppressWarnings("unchecked") - public T deserialize(byte[] bytes, Class expectedType) throws UnsupportedConstantPoolTypeException { - VariableLengthIntBuffer buffer = new VariableLengthIntBuffer(bytes); - - while (buffer.hasRemaining()) { - int classCPI = buffer.get(); - if (classCPI == VariableLengthIntBuffer.NULL) { - pushNode(null); - } else { - Class clazz = cp.getClass(classCPI); - if (clazz.isArray()) { - int lengthCPI = buffer.get(); - if (lengthCPI == VariableLengthIntBuffer.NULL) { - pushArray(null); - } else { - pushArray((Node[]) Array.newInstance(clazz.getComponentType(), cp.getInt(lengthCPI))); - } - } else { - pushNode(invokeDeserialize(buffer, clazz.asSubclass(Node.class))); - } - } - } - T returnNode = (T) popNode(null, expectedType); - - assert stack.dynamicStack.isEmpty(); - - return returnNode; - } - - private void pushNode(Node node) { - stack.push(node); - } - - private void pushArray(Node[] array) { - stack.pushStack(array); - } - - private Node[] popArray(Node parent, Class expectedType) { - Node[] array = (Node[]) stack.popStack(); - if (array != null) { - assertType(array, expectedType); - for (int i = 0; i < array.length; i++) { - updateParent(parent, array[i]); - } - } - return array; - } - - private Node popNode(Node parent, Class expectedType) { - Object o = stack.pop(); - assertType(o, expectedType); - updateParent(parent, (Node) o); - return (Node) o; - } - - private static void assertType(Object o, Class expectedType) { - if (o != null && !expectedType.isAssignableFrom(o.getClass())) { - throw new AssertionError("Expected element type '" + expectedType.getName() + "' but was '" + o.getClass().getName() + "'."); - } - } - - private Node invokeDeserialize(VariableLengthIntBuffer buffer, Class nodeClass) throws UnsupportedConstantPoolTypeException { - if (nodeClass == null) { - return null; - } - - Object object; - try { - object = unsafe.allocateInstance(nodeClass); - } catch (InstantiationException e) { - throw new RuntimeException("Unable to allocate truffle node " + nodeClass, e); - } - if (!(object instanceof Node)) { - throw new RuntimeException("Class is not a truffle node " + nodeClass); - } - - Node node = (Node) object; - - NodeFieldAccessor[] nodeFields = NodeClass.get(nodeClass).getFields(); - deserializeChildrenFields(node, nodeFields); - deserializeChildFields(node, nodeFields); - deserializeDataFields(buffer, node, nodeFields); - - return node; - } - - private void deserializeDataFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { - for (int i = 0; i < nodeFields.length; i++) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.DATA) { - Class fieldClass = field.getType(); - long offset = field.getOffset(); - - // source sections are not serialized - // TODO add support for source sections - if (field.getType().isAssignableFrom(SourceSection.class)) { - continue; - } - - int cpi = buffer.get(); - if (cpi == VariableLengthIntBuffer.NULL) { - deserializeDataFieldsLengthNull(nodeInstance, fieldClass, offset); - } else { - deserializeDataFieldsDefault(nodeInstance, fieldClass, offset, cpi); - } - } - } - } - - private void deserializeDataFieldsDefault(Node nodeInstance, Class fieldClass, long offset, int cpi) { - if (fieldClass == int.class) { - unsafe.putInt(nodeInstance, offset, cp.getInt(cpi)); - } else if (fieldClass == long.class) { - unsafe.putLong(nodeInstance, offset, cp.getLong(cpi)); - } else if (fieldClass == float.class) { - unsafe.putFloat(nodeInstance, offset, cp.getFloat(cpi)); - } else if (fieldClass == double.class) { - unsafe.putDouble(nodeInstance, offset, cp.getDouble(cpi)); - } else if (fieldClass == byte.class) { - unsafe.putByte(nodeInstance, offset, (byte) cp.getInt(cpi)); - } else if (fieldClass == short.class) { - unsafe.putShort(nodeInstance, offset, (short) cp.getInt(cpi)); - } else if (fieldClass == char.class) { - unsafe.putChar(nodeInstance, offset, (char) cp.getInt(cpi)); - } else if (fieldClass == boolean.class) { - unsafe.putBoolean(nodeInstance, offset, cp.getInt(cpi) == 1 ? true : false); - } else if (fieldClass == Integer.class) { - unsafe.putObject(nodeInstance, offset, cp.getInt(cpi)); - } else if (fieldClass == Long.class) { - unsafe.putObject(nodeInstance, offset, cp.getLong(cpi)); - } else if (fieldClass == Float.class) { - unsafe.putObject(nodeInstance, offset, cp.getFloat(cpi)); - } else if (fieldClass == Double.class) { - unsafe.putObject(nodeInstance, offset, cp.getDouble(cpi)); - } else if (fieldClass == Byte.class) { - unsafe.putObject(nodeInstance, offset, (byte) cp.getInt(cpi)); - } else if (fieldClass == Short.class) { - unsafe.putObject(nodeInstance, offset, (short) cp.getInt(cpi)); - } else if (fieldClass == Character.class) { - unsafe.putObject(nodeInstance, offset, (char) cp.getInt(cpi)); - } else if (fieldClass == Boolean.class) { - unsafe.putObject(nodeInstance, offset, cp.getInt(cpi) == 1 ? Boolean.TRUE : Boolean.FALSE); - } else { - unsafe.putObject(nodeInstance, offset, cp.getObject(fieldClass, cpi)); - } - } - - private static void deserializeDataFieldsLengthNull(Node nodeInstance, Class fieldClass, long offset) { - if (fieldClass == int.class) { - unsafe.putInt(nodeInstance, offset, 0); - } else if (fieldClass == long.class) { - unsafe.putLong(nodeInstance, offset, 0L); - } else if (fieldClass == float.class) { - unsafe.putFloat(nodeInstance, offset, 0.0F); - } else if (fieldClass == double.class) { - unsafe.putDouble(nodeInstance, offset, 0.0D); - } else if (fieldClass == byte.class) { - unsafe.putByte(nodeInstance, offset, (byte) 0); - } else if (fieldClass == short.class) { - unsafe.putShort(nodeInstance, offset, (short) 0); - } else if (fieldClass == char.class) { - unsafe.putChar(nodeInstance, offset, (char) 0); - } else if (fieldClass == boolean.class) { - unsafe.putBoolean(nodeInstance, offset, false); - } else { - unsafe.putObject(nodeInstance, offset, null); - } - } - - private void deserializeChildFields(Node parent, NodeFieldAccessor[] nodeFields) { - for (int i = nodeFields.length - 1; i >= 0; i--) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.CHILD) { - unsafe.putObject(parent, field.getOffset(), popNode(parent, field.getType())); - } - } - } - - private void deserializeChildrenFields(Node parent, NodeFieldAccessor[] nodeFields) { - for (int i = nodeFields.length - 1; i >= 0; i--) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.CHILDREN) { - unsafe.putObject(parent, field.getOffset(), popArray(parent, field.getType())); - } - } - } - - private static Node updateParent(Node parent, Node child) { - if (child != null) { - NodeClass nodeClass = NodeClass.get(child.getClass()); - nodeClass.getNodeClassField().putObject(child, nodeClass); - nodeClass.getParentField().putObject(child, parent); - } - return child; - } - - private static Unsafe loadUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException e) { - } - try { - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeInstance.setAccessible(true); - return (Unsafe) theUnsafeInstance.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); - } - } - - private static class HierarchicalStack { - - private static final Object NULL_STACK = new Object(); - - private final List dynamicStack = new ArrayList<>(); - - void pushStack(Object[] array) { - if (array == null) { - dynamicStack.add(NULL_STACK); - } else { - dynamicStack.add(new FixedSizeNodeStack(array)); - } - } - - private FixedSizeNodeStack getTosStack() { - if (dynamicStack.isEmpty()) { - return null; - } - Object peekTos = dynamicStack.get(dynamicStack.size() - 1); - if (peekTos != null && peekTos.getClass() == FixedSizeNodeStack.class) { - return (FixedSizeNodeStack) peekTos; - } - return null; - } - - Object[] popStack() { - Object tos = dynamicStack.remove(dynamicStack.size() - 1); - if (tos == NULL_STACK) { - return null; - } - return ((FixedSizeNodeStack) tos).getArray(); - } - - void push(Object o) { - FixedSizeNodeStack tosStack = getTosStack(); - if (tosStack != null && !tosStack.isFull()) { - tosStack.push(o); - } else { - dynamicStack.add(o); - } - } - - Object pop() { - FixedSizeNodeStack tosStack = getTosStack(); - Object value; - if (tosStack != null) { - assert !tosStack.isEmpty(); - value = tosStack.pop(); - } else { - value = dynamicStack.remove(dynamicStack.size() - 1); - } - assert value != NULL_STACK; - return value; - } - - } - - private static class FixedSizeNodeStack { - - private final Object[] array; - - private int tos; - - FixedSizeNodeStack(Object[] array) { - this.array = array; - } - - boolean isFull() { - return tos == array.length; - } - - boolean isEmpty() { - return tos == 0; - } - - private void push(Object node) { - if (tos >= array.length) { - throw new ArrayIndexOutOfBoundsException(); - } - unsafe.putObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * (long) (tos++), node); - } - - private Object pop() { - if (tos <= 0) { - throw new ArrayIndexOutOfBoundsException(); - } - return unsafe.getObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * (long) (--tos)); - } - - private Object[] getArray() { - return array; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/PostOrderSerializer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/PostOrderSerializer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.serial; - -import java.lang.reflect.*; -import java.nio.*; - -import sun.misc.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; -import com.oracle.truffle.api.source.*; - -/** - * Experimental API. May change without notice. - */ -public final class PostOrderSerializer { - - private static final Unsafe unsafe = loadUnsafe(); - - private final SerializerConstantPool cp; - - /** - * Constructs a new deserializer using a custom {@link SerializerConstantPool} implementation. - * For the {@link SerializerConstantPool} implementation at least the following methods must be - * implemented: - *
    - *
  • {@link SerializerConstantPool#putInt(int)}
  • - *
  • {@link SerializerConstantPool#putClass(Class)}
  • - *
- */ - public PostOrderSerializer(SerializerConstantPool cp) { - this.cp = cp; - } - - /** - * Serializes the node AST and returns the serialized data as byte array. - * - * @param node the root node that represents the Truffle AST that should be serialized. - * @return a trimmed byte array that contains the serialized data. - * - * @throws UnsupportedConstantPoolTypeException thrown if a type is encountered that is not - * supported by the constant pool implementation. - */ - public byte[] serialize(Node node) throws UnsupportedConstantPoolTypeException { - VariableLengthIntBuffer buffer = new VariableLengthIntBuffer(ByteBuffer.allocate(512)); - serialize(buffer, node); - return buffer.getBytes(); - } - - private void serialize(VariableLengthIntBuffer buffer, Node node) throws UnsupportedConstantPoolTypeException { - if (node == null) { - buffer.put(VariableLengthIntBuffer.NULL); - return; - } - Class nodeClass = node.getClass(); - - NodeFieldAccessor[] nodeFields = NodeClass.get(nodeClass).getFields(); - serializeChildFields(buffer, node, nodeFields); - serializeChildrenFields(buffer, node, nodeFields); - buffer.put(cp.putClass(node.getClass())); - serializeDataFields(buffer, node, nodeFields); - } - - private void serializeDataFields(VariableLengthIntBuffer buffer, Node node, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { - for (int i = 0; i < nodeFields.length; i++) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.DATA) { - Class fieldClass = field.getType(); - long offset = field.getOffset(); - int cpi; - - if (field.getType().isAssignableFrom(SourceSection.class)) { - continue; - } - - if (fieldClass == int.class) { - cpi = cp.putInt(unsafe.getInt(node, offset)); - } else if (fieldClass == long.class) { - cpi = cp.putLong(unsafe.getLong(node, offset)); - } else if (fieldClass == float.class) { - cpi = cp.putFloat(unsafe.getFloat(node, offset)); - } else if (fieldClass == double.class) { - cpi = cp.putDouble(unsafe.getDouble(node, offset)); - } else if (fieldClass == byte.class) { - cpi = cp.putInt(unsafe.getByte(node, offset)); - } else if (fieldClass == short.class) { - cpi = cp.putInt(unsafe.getShort(node, offset)); - } else if (fieldClass == char.class) { - cpi = cp.putInt(unsafe.getChar(node, offset)); - } else if (fieldClass == boolean.class) { - cpi = cp.putInt(unsafe.getBoolean(node, offset) ? 1 : 0); - } else { - cpi = serializeDataFieldsObject(node, fieldClass, offset); - } - - buffer.put(cpi); - } - } - } - - private int serializeDataFieldsObject(Node node, Class fieldClass, long offset) { - Object value = unsafe.getObject(node, offset); - if (value == null) { - return VariableLengthIntBuffer.NULL; - } else if (fieldClass == Integer.class) { - return cp.putInt((Integer) value); - } else if (fieldClass == Long.class) { - return cp.putLong((Long) value); - } else if (fieldClass == Float.class) { - return cp.putFloat((Float) value); - } else if (fieldClass == Double.class) { - return cp.putDouble((Double) value); - } else if (fieldClass == Byte.class) { - return cp.putInt((Byte) value); - } else if (fieldClass == Short.class) { - return cp.putInt((Short) value); - } else if (fieldClass == Character.class) { - return cp.putInt((Character) value); - } else if (fieldClass == Boolean.class) { - return cp.putInt((Boolean) value ? 1 : 0); - } else { - return cp.putObject(fieldClass, value); - } - } - - private void serializeChildrenFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { - for (int i = 0; i < nodeFields.length; i++) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.CHILDREN) { - Object childArrayObject = unsafe.getObject(nodeInstance, field.getOffset()); - if (childArrayObject != null && !(childArrayObject instanceof Node[])) { - throw new AssertionError("Node children must be instanceof Node[]"); - } - - buffer.put(cp.putClass(field.getType())); - - Node[] childArray = (Node[]) childArrayObject; - if (childArray == null) { - buffer.put(VariableLengthIntBuffer.NULL); - } else { - buffer.put(cp.putInt(childArray.length)); - - for (int j = 0; j < childArray.length; j++) { - serialize(buffer, childArray[j]); - } - } - } - } - } - - private void serializeChildFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { - for (int i = 0; i < nodeFields.length; i++) { - NodeFieldAccessor field = nodeFields[i]; - if (field.getKind() == NodeFieldKind.CHILD) { - Object childObject = unsafe.getObject(nodeInstance, field.getOffset()); - if (childObject != null && !(childObject instanceof Node)) { - throw new AssertionError("Node children must be instanceof Node"); - } - serialize(buffer, (Node) childObject); - } - } - } - - private static Unsafe loadUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException e) { - } - try { - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeInstance.setAccessible(true); - return (Unsafe) theUnsafeInstance.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/SerializerConstantPool.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/SerializerConstantPool.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.serial; - -/** - * Experimental API. May change without notice. This interface is used as bridge between the - * {@link PostOrderDeserializer}, {@link PostOrderSerializer} and underlying constant pool - * implementation. A constant pool stores a value and returns an identifying index, with which the - * object can later be returned from the pool again. All methods of this class are optional and may - * throw a {@link UnsupportedOperationException}. - */ -public interface SerializerConstantPool { - - /** - * Returns the constant pool index of a value that is not a java native type, a java - * native-wrapper class or a {@link Class} instance. The implementor should support all - * additional types that are necessary to serialize a truffle AST for a specific truffle - * implementation. If a type is not supported by this constant pool implementation a - * {@link UnsupportedConstantPoolTypeException} should be thrown. - * - * @param clazz the {@link Class} of the value - * @param value the value to be stored. Must be at least a subclass of the given clazz. - * @return the constant pool index - * @throws UnsupportedConstantPoolTypeException if a type is not supported for persistence in - * the constant pool. - */ - int putObject(Class clazz, Object value) throws UnsupportedConstantPoolTypeException; - - /** - * Stores a value in the constant pool that is not a java native type, a java native-wrapper - * class or a {@link Class} instance. The implementor should support all additional types that - * are necessary to serialize a truffle AST for a specific truffle implementation. If a type is - * not supported by this constant pool implementation a - * {@link UnsupportedConstantPoolTypeException} should be thrown. - * - * @param clazz the {@link Class} of the value in the constant pool. - * @param cpi the previously returned index - * @return the value stored inside the constant pool - * @throws UnsupportedConstantPoolTypeException if a type is not supported for persistence in - * the constant pool. - * @throws IllegalArgumentException if the provided cpi is not a valid constant pool index. - */ - Object getObject(Class clazz, int cpi) throws UnsupportedConstantPoolTypeException; - - /** - * Stores a Class instance in the constant pool and returns the constant pool index. - * - * @param value the class to store - * @return the new or existing constant pool index of the Class - */ - int putClass(Class value); - - /** - * Returns the {@link Class} instance to the given constant pool index. - * - * @param cpi the constant pool index - * @return stored value - * @throws IllegalArgumentException if the constant pool indes is invalid. - */ - Class getClass(int cpi); - - /** - * Stores an int value in the constant pool and returns the constant pool index. - * - * @param value the value to store - * @return the new or existing constant pool index of the value - */ - int putInt(int value); - - /** - * Returns the stored int value to the given constant pool index from the constant pool. - * - * @param cpi the constant pool index - * @return stored value - * @throws IllegalArgumentException if the constant pool index is invalid. - */ - int getInt(int cpi); - - /** - * Stores a long value in the constant pool and returns the constant pool index. - * - * @param value the value to store - * @return the new or existing constant pool index of the value - */ - int putLong(long value); - - /** - * Returns the stored long value to the given constant pool index from the constant pool. - * - * @param cpi the constant pool index - * @return the stored value - * @throws IllegalArgumentException if the constant pool index is invalid. - */ - long getLong(int cpi); - - /** - * Stores a double value in the constant pool and returns the constant pool index. - * - * @param value the value to store - * @return the new or existing constant pool index of the value - */ - int putDouble(double value); - - /** - * Returns the stored double value to the given constant pool index from the constant pool. - * - * @param cpi the constant pool index - * @return the stored value - * @throws IllegalArgumentException if the constant pool index is invalid. - */ - double getDouble(int cpi); - - /** - * Stores a float value in the constant pool and returns the constant pool index. - * - * @param value the value to store - * @return the new or existing constant pool index of the value - */ - int putFloat(float value); - - /** - * Returns the stored float value to the given constant pool index from the constant pool. - * - * @param cpi the constant pool index - * @return the stored value - * @throws IllegalArgumentException if the constant pool index is invalid. - */ - float getFloat(int cpi); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/UnsupportedConstantPoolTypeException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/UnsupportedConstantPoolTypeException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.serial; - -/** - * Experimental API. May change without notice. - */ -public class UnsupportedConstantPoolTypeException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public UnsupportedConstantPoolTypeException() { - super(); - } - - public UnsupportedConstantPoolTypeException(String message, Throwable cause) { - super(message, cause); - } - - public UnsupportedConstantPoolTypeException(String message) { - super(message); - } - - public UnsupportedConstantPoolTypeException(Throwable cause) { - super(cause); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.serial; - -import java.nio.*; - -/** - * Experimental API. May change without notice. Simple variable length unsigned int buffer backed by - * a byte buffer. - */ -public class VariableLengthIntBuffer { - - public static final int NULL = -1; - - private ByteBuffer buffer; - - public VariableLengthIntBuffer(ByteBuffer buffer) { - this.buffer = buffer; - } - - public VariableLengthIntBuffer(byte[] array) { - buffer = ByteBuffer.wrap(array); - } - - /** - * Returns the backing byte buffer. - */ - public ByteBuffer getBuffer() { - return buffer; - } - - public byte[] getBytes() { - int pos = buffer.position(); - byte[] bytes = new byte[buffer.position()]; - buffer.rewind(); - buffer.get(bytes); - buffer.position(pos); - return bytes; - } - - public int get() { - byte peekByte = buffer.get(buffer.position()); - if ((peekByte & 0x80) == 0) { - // single byte encoding with prefix 0 (range 127) - return buffer.get(); // no bit to be masked - } else { - if (peekByte == (byte) 0xFF) { - buffer.get(); // skip one byte - return NULL; - } - int result = buffer.getInt() & 0x7FFF_FFFF; // first bit masked out - assert (result & 0x4000_0000) == 0; - return result; - } - } - - public void put(int i) { - ensureCapacity(); - if (i == NULL) { - buffer.put((byte) 0xFF); - } else if ((i & 0xFFFF_FF80) == 0) { // 7 bits data - buffer.put((byte) i); - } else if ((i & 0xC000_0000) == 0) { // 32 bits data - buffer.putInt(i | 0x8000_0000); // append leading 1 - } else { - throw new IllegalArgumentException("Integer out of encodeable " + i); - } - } - - private void ensureCapacity() { - if (buffer.position() + 4 > buffer.capacity()) { - ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() * 2); - - int pos = buffer.position(); - buffer.rewind(); - newBuffer.put(buffer); - newBuffer.position(pos); - - buffer = newBuffer; - } - } - - public boolean hasRemaining() { - return buffer.hasRemaining(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/script/TruffleScriptEngineFactory.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/script/TruffleScriptEngineFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.script; - -import javax.script.*; - -/** - * Tool access to the creation of Truffle execution engines. - */ -public abstract class TruffleScriptEngineFactory implements ScriptEngineFactory { - - // TODO (mlvdv) first step, based on a suggestion from NetBeans - /** - * To be called by each concrete factory just after each engine instance is created, presenting - * an opportunity for an IDE to interrupt in a language-independent way. - * - * @param engine a just-created engine - */ - protected final void engineCreated(ScriptEngine engine) { - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/BytesDecoder.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/BytesDecoder.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.nio.charset.*; -import java.util.*; - -/** - * For a language where strings do not map into Java strings, provides utilities to find line - * endings and to decode raw bytes into an approximate representation for tools to display. - *

- * See {@link Source#fromBytes}. - */ -public interface BytesDecoder { - - String decode(byte[] bytes, int byteIndex, int length); - - void decodeLines(byte[] bytes, int byteIndex, int length, LineMarker lineMarker); - - public interface LineMarker { - - void markLine(int index); - - } - - public static class UTF8BytesDecoder implements BytesDecoder { - - @Override - public String decode(byte[] bytes, int byteIndex, int length) { - return new String(Arrays.copyOfRange(bytes, byteIndex, byteIndex + length), StandardCharsets.UTF_8); - } - - @Override - public void decodeLines(byte[] bytes, int byteIndex, int length, LineMarker lineMarker) { - for (int n = byteIndex; n < byteIndex + length; n++) { - if (bytes[n] == '\n') { - lineMarker.markLine(n + 1); - } - } - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/LineLocation.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/LineLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.util.*; - -/** - * A specification for a location in guest language source, expressed as a line number in a specific - * instance of {@link Source}, suitable for hash table keys with equality defined in terms of - * content. - */ -public interface LineLocation { - - Source getSource(); - - /** - * Gets the 1-based number of a line in the source. - */ - int getLineNumber(); - - String getShortDescription(); - - /** - * Default comparator by (1) textual path name, (2) line number. - */ - Comparator COMPARATOR = new Comparator() { - - public int compare(LineLocation l1, LineLocation l2) { - final int sourceResult = l1.getSource().getPath().compareTo(l2.getSource().getPath()); - if (sourceResult != 0) { - return sourceResult; - } - return Integer.compare(l1.getLineNumber(), l2.getLineNumber()); - } - - }; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/NullSourceSection.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/NullSourceSection.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * A special subtype of {@link SourceSection} that represents unavailable source, e.g. for language - * builtins. - */ -public class NullSourceSection implements SourceSection { - - private final String kind; - private final String name; - private final String asCode; - - /** - * Placeholder for source that is unavailable, e.g. for language builtins. - * - * @param kind the general category, e.g. "JS builtin" - * @param name specific name for this section - */ - public NullSourceSection(String kind, String name) { - this(kind, name, kind); - } - - /** - * Placeholder for source that is unavailable, e.g. for language builtins. - * - * @param kind the general category, e.g. "JS builtin" - * @param name specific name for this section - * @param asCode string to return when {@link #getCode()} is called - */ - public NullSourceSection(String kind, String name, String asCode) { - this.kind = kind; - this.name = name; - this.asCode = asCode; - } - - public final Source getSource() { - return null; - } - - public final int getStartLine() { - throw new UnsupportedOperationException(this.toString()); - } - - public final LineLocation getLineLocation() { - throw new UnsupportedOperationException(this.toString()); - } - - public final int getStartColumn() { - throw new UnsupportedOperationException(this.toString()); - } - - public int getEndLine() { - throw new UnsupportedOperationException(this.toString()); - } - - public int getEndColumn() { - throw new UnsupportedOperationException(this.toString()); - } - - public final int getCharIndex() { - throw new UnsupportedOperationException(this.toString()); - } - - public final int getCharLength() { - throw new UnsupportedOperationException(this.toString()); - } - - public final int getCharEndIndex() { - throw new UnsupportedOperationException(this.toString()); - } - - public final String getIdentifier() { - return name; - } - - public final String getCode() { - return asCode; - } - - public final String getShortDescription() { - return kind + ": " + name; - } - - @Override - public String toString() { - return getShortDescription(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1553 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import java.lang.ref.*; -import java.net.*; -import java.util.*; - -import com.oracle.truffle.api.instrument.*; - -/** - * Representation of a guest language source code unit and its contents. Sources originate in - * several ways: - *

    - *
  • Literal: An anonymous text string: not named and not indexed. These should - * be considered value objects; equality is defined based on contents.
    - * See {@link Source#fromText(CharSequence, String)}
  • - *

    - *

  • Named Literal: A text string that can be retrieved by name as if it were a - * file, but without any assumption that the name is related to a file path. Creating a new literal - * with an already existing name will replace its predecessor in the index.
    - * See {@link Source#fromNamedText(CharSequence, String)}
    - * See {@link Source#find(String)}
  • - *

    - *

  • File: Each file is represented as a canonical object, indexed by the - * absolute, canonical path name of the file. File contents are read lazily and contents - * optionally cached.
    - * See {@link Source#fromFileName(String)}
    - * See {@link Source#fromFileName(String, boolean)}
    - * See {@link Source#find(String)}
  • - *

    - *

  • URL: Each URL source is represented as a canonical object, indexed by the - * URL. Contents are read eagerly and cached.
    - * See {@link Source#fromURL(URL, String)}
    - * See {@link Source#find(String)}
  • - *

    - *

  • Reader: Contents are read eagerly and treated as an anonymous - * (non-indexed) Literal .
    - * See {@link Source#fromReader(Reader, String)}
  • - *

    - *

  • Sub-Source: A representation of the contents of a sub-range of another - * {@link Source}.
    - * See @link {@link Source#subSource(Source, int, int)}
    - * See @link {@link Source#subSource(Source, int)}
  • - *

    - *

  • AppendableSource: Literal contents are provided by the client, - * incrementally, after the instance is created.
    - * See {@link Source#fromAppendableText(String)}
    - * See {@link Source#fromNamedAppendableText(String)}
  • - *
- *

- * File cache: - *

    - *
  1. File content caching is optional, on by default.
  2. - *
  3. The first access to source file contents will result in the contents being read, and (if - * enabled) cached.
  4. - *
  5. If file contents have been cached, access to contents via {@link Source#getInputStream()} or - * {@link Source#getReader()} will be provided from the cache.
  6. - *
  7. Any access to file contents via the cache will result in a timestamp check and possible cache - * reload.
  8. - *
- *

- * - * @see SourceTag - * @see SourceListener - */ -public abstract class Source { - - // TODO (mlvdv) consider canonicalizing and reusing SourceSection instances - // TOOD (mlvdv) connect SourceSections into a spatial tree for fast geometric lookup - - public enum Tags implements SourceTag { - - /** - * From bytes. - */ - FROM_BYTES("bytes", "read from bytes"), - - /** - * Read from a file. - */ - FROM_FILE("file", "read from a file"), - - /** - * From literal text. - */ - FROM_LITERAL("literal", "from literal text"), - - /** - * From a {@linkplain java.io.Reader Reader}. - */ - FROM_READER("reader", "read from a Java Reader"), - - /** - * Read from a URL. - */ - FROM_URL("URL", "read from a URL"); - - private final String name; - private final String description; - - private Tags(String name, String description) { - this.name = name; - this.description = description; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - } - - /** - * All Sources that have been created. - */ - private static final List> allSources = Collections.synchronizedList(new ArrayList>()); - - /** - * Index of all named sources. - */ - private static final Map> nameToSource = new HashMap<>(); - - private static boolean fileCacheEnabled = true; - - private static final List sourceListeners = new ArrayList<>(); - - /** - * Locates an existing instance by the name under which it was indexed. - */ - public static Source find(String name) { - final WeakReference nameRef = nameToSource.get(name); - return nameRef == null ? null : nameRef.get(); - } - - /** - * Gets the canonical representation of a source file, whose contents will be read lazily and - * then cached. - * - * @param fileName name - * @param reset forces any existing {@link Source} cache to be cleared, forcing a re-read - * @return canonical representation of the file's contents. - * @throws IOException if the file can not be read - */ - public static Source fromFileName(String fileName, boolean reset) throws IOException { - - final WeakReference nameRef = nameToSource.get(fileName); - Source source = nameRef == null ? null : nameRef.get(); - if (source == null) { - final File file = new File(fileName); - if (!file.canRead()) { - throw new IOException("Can't read file " + fileName); - } - final String path = file.getCanonicalPath(); - final WeakReference pathRef = nameToSource.get(path); - source = pathRef == null ? null : pathRef.get(); - if (source == null) { - source = new FileSource(file, fileName, path); - nameToSource.put(path, new WeakReference<>(source)); - } - } - if (reset) { - source.reset(); - } - notifyNewSource(source).tagAs(Tags.FROM_FILE); - return source; - } - - /** - * Gets the canonical representation of a source file, whose contents will be read lazily and - * then cached. - * - * @param fileName name - * @return canonical representation of the file's contents. - * @throws IOException if the file can not be read - */ - public static Source fromFileName(String fileName) throws IOException { - return fromFileName(fileName, false); - } - - /** - * Gets the canonical representation of a source file, whose contents have already been read and - * need not be read again. It is confirmed that the file resolves to a file name, so it can be - * indexed by canonical path. It is not confirmed that the text supplied agrees with the file's - * contents or even whether the file is readable. - * - * @param chars textual source code already read from the file - * @param fileName - * @return canonical representation of the file's contents. - * @throws IOException if the file cannot be found - */ - public static Source fromFileName(CharSequence chars, String fileName) throws IOException { - - final WeakReference nameRef = nameToSource.get(fileName); - Source source = nameRef == null ? null : nameRef.get(); - if (source == null) { - final File file = new File(fileName); - // We are going to trust that the fileName is readable. - final String path = file.getCanonicalPath(); - final WeakReference pathRef = nameToSource.get(path); - source = pathRef == null ? null : pathRef.get(); - if (source == null) { - source = new FileSource(file, fileName, path, chars); - nameToSource.put(path, new WeakReference<>(source)); - } - } - notifyNewSource(source).tagAs(Tags.FROM_FILE); - return source; - } - - /** - * Creates an anonymous source from literal text: not named and not indexed. - * - * @param chars textual source code - * @param description a note about the origin, for error messages and debugging - * @return a newly created, non-indexed source representation - */ - public static Source fromText(CharSequence chars, String description) { - assert chars != null; - final LiteralSource source = new LiteralSource(description, chars.toString()); - notifyNewSource(source).tagAs(Tags.FROM_LITERAL); - return source; - } - - /** - * Creates an anonymous source from literal text that is provided incrementally after creation: - * not named and not indexed. - * - * @param description a note about the origin, for error messages and debugging - * @return a newly created, non-indexed, initially empty, appendable source representation - */ - public static Source fromAppendableText(String description) { - final Source source = new AppendableLiteralSource(description); - notifyNewSource(source).tagAs(Tags.FROM_LITERAL); - return source; - } - - /** - * Creates a source from literal text that can be retrieved by name, with no assumptions about - * the structure or meaning of the name. If the name is already in the index, the new instance - * will replace the previously existing instance in the index. - * - * @param chars textual source code - * @param name string to use for indexing/lookup - * @return a newly created, source representation - */ - public static Source fromNamedText(CharSequence chars, String name) { - final Source source = new LiteralSource(name, chars.toString()); - nameToSource.put(name, new WeakReference<>(source)); - notifyNewSource(source).tagAs(Tags.FROM_LITERAL); - return source; - } - - /** - * Creates a source from literal text that is provided incrementally after creation and which - * can be retrieved by name, with no assumptions about the structure or meaning of the name. If - * the name is already in the index, the new instance will replace the previously existing - * instance in the index. - * - * @param name string to use for indexing/lookup - * @return a newly created, indexed, initially empty, appendable source representation - */ - public static Source fromNamedAppendableText(String name) { - final Source source = new AppendableLiteralSource(name); - nameToSource.put(name, new WeakReference<>(source)); - notifyNewSource(source).tagAs(Tags.FROM_LITERAL); - return source; - } - - /** - * Creates a {@linkplain Source Source instance} that represents the contents of a sub-range of - * an existing {@link Source}. - * - * @param base an existing Source instance - * @param baseCharIndex 0-based index of the first character of the sub-range - * @param length the number of characters in the sub-range - * @return a new instance representing a sub-range of another Source - * @throws IllegalArgumentException if the specified sub-range is not contained in the base - */ - public static Source subSource(Source base, int baseCharIndex, int length) { - final SubSource subSource = SubSource.create(base, baseCharIndex, length); - return subSource; - } - - /** - * Creates a {@linkplain Source Source instance} that represents the contents of a sub-range at - * the end of an existing {@link Source}. - * - * @param base an existing Source instance - * @param baseCharIndex 0-based index of the first character of the sub-range - * @return a new instance representing a sub-range at the end of another Source - * @throws IllegalArgumentException if the index is out of range - */ - public static Source subSource(Source base, int baseCharIndex) { - return subSource(base, baseCharIndex, base.getLength() - baseCharIndex); - } - - /** - * Creates a source whose contents will be read immediately from a URL and cached. - * - * @param url - * @param description identifies the origin, possibly useful for debugging - * @return a newly created, non-indexed source representation - * @throws IOException if reading fails - */ - public static Source fromURL(URL url, String description) throws IOException { - final URLSource source = URLSource.get(url, description); - notifyNewSource(source).tagAs(Tags.FROM_URL); - return source; - } - - /** - * Creates a source whose contents will be read immediately and cached. - * - * @param reader - * @param description a note about the origin, possibly useful for debugging - * @return a newly created, non-indexed source representation - * @throws IOException if reading fails - */ - public static Source fromReader(Reader reader, String description) throws IOException { - final LiteralSource source = new LiteralSource(description, read(reader)); - notifyNewSource(source).tagAs(Tags.FROM_READER); - return source; - } - - /** - * Creates a source from raw bytes. This can be used if the encoding of strings in your language - * is not compatible with Java strings, or if your parser returns byte indices instead of - * character indices. The returned source is then indexed by byte, not by character. - * - * @param bytes the raw bytes of the source - * @param description a note about the origin, possibly useful for debugging - * @param decoder how to decode the bytes into Java strings - * @return a newly created, non-indexed source representation - */ - public static Source fromBytes(byte[] bytes, String description, BytesDecoder decoder) { - return fromBytes(bytes, 0, bytes.length, description, decoder); - } - - /** - * Creates a source from raw bytes. This can be used if the encoding of strings in your language - * is not compatible with Java strings, or if your parser returns byte indices instead of - * character indices. The returned source is then indexed by byte, not by character. Offsets are - * relative to byteIndex. - * - * @param bytes the raw bytes of the source - * @param byteIndex where the string starts in the byte array - * @param length the length of the string in the byte array - * @param description a note about the origin, possibly useful for debugging - * @param decoder how to decode the bytes into Java strings - * @return a newly created, non-indexed source representation - */ - public static Source fromBytes(byte[] bytes, int byteIndex, int length, String description, BytesDecoder decoder) { - final BytesSource source = new BytesSource(description, bytes, byteIndex, length, decoder); - notifyNewSource(source).tagAs(Tags.FROM_BYTES); - return source; - } - - // TODO (mlvdv) enable per-file choice whether to cache? - /** - * Enables/disables caching of file contents, disabled by default. Caching of sources - * created from literal text or readers is always enabled. - */ - public static void setFileCaching(boolean enabled) { - fileCacheEnabled = enabled; - } - - /** - * Returns all {@link Source}s holding a particular {@link SyntaxTag}, or the whole collection - * of Sources if the specified tag is {@code null}. - * - * @return A collection of Sources containing the given tag. - */ - public static Collection findSourcesTaggedAs(SourceTag tag) { - final List taggedSources = new ArrayList<>(); - synchronized (allSources) { - for (WeakReference ref : allSources) { - Source source = ref.get(); - if (source != null) { - if (tag == null || source.isTaggedAs(tag)) { - taggedSources.add(ref.get()); - } - } - } - } - return taggedSources; - } - - /** - * Adds a {@link SourceListener} to receive events. - */ - public static void addSourceListener(SourceListener listener) { - assert listener != null; - sourceListeners.add(listener); - } - - /** - * Removes a {@link SourceListener}. Ignored if listener not found. - */ - public static void removeSourceListener(SourceListener listener) { - sourceListeners.remove(listener); - } - - private static Source notifyNewSource(Source source) { - allSources.add(new WeakReference<>(source)); - for (SourceListener listener : sourceListeners) { - listener.sourceCreated(source); - } - return source; - } - - private static String read(Reader reader) throws IOException { - final BufferedReader bufferedReader = new BufferedReader(reader); - final StringBuilder builder = new StringBuilder(); - final char[] buffer = new char[1024]; - - while (true) { - final int n = bufferedReader.read(buffer); - if (n == -1) { - break; - } - builder.append(buffer, 0, n); - } - - return builder.toString(); - } - - private final ArrayList tags = new ArrayList<>(); - - private Source() { - } - - private TextMap textMap = null; - - protected abstract void reset(); - - public final boolean isTaggedAs(SourceTag tag) { - assert tag != null; - return tags.contains(tag); - } - - public final Collection getSourceTags() { - return Collections.unmodifiableCollection(tags); - } - - /** - * Adds a {@linkplain SourceTag tag} to the set of tags associated with this {@link Source}; - * {@code no-op} if already in the set. - * - * @return this - */ - public final Source tagAs(SourceTag tag) { - assert tag != null; - if (!tags.contains(tag)) { - tags.add(tag); - for (SourceListener listener : sourceListeners) { - listener.sourceTaggedAs(this, tag); - } - } - return this; - } - - /** - * Returns the name of this resource holding a guest language program. An example would be the - * name of a guest language source code file. - * - * @return the name of the guest language program - */ - public abstract String getName(); - - /** - * Returns a short version of the name of the resource holding a guest language program (as - * described in @getName). For example, this could be just the name of the file, rather than a - * full path. - * - * @return the short name of the guest language program - */ - public abstract String getShortName(); - - /** - * The normalized, canonical name if the source is a file. - */ - public abstract String getPath(); - - /** - * The URL if the source is retrieved via URL. - */ - public abstract URL getURL(); - - /** - * Access to the source contents. - */ - public abstract Reader getReader(); - - /** - * Access to the source contents. - */ - public final InputStream getInputStream() { - return new ByteArrayInputStream(getCode().getBytes()); - } - - /** - * Gets the number of characters in the source. - */ - public final int getLength() { - return getTextMap().length(); - } - - /** - * Returns the complete text of the code. - */ - public abstract String getCode(); - - /** - * Returns a subsection of the code test. - */ - public String getCode(int charIndex, int charLength) { - return getCode().substring(charIndex, charIndex + charLength); - } - - /** - * Gets the text (not including a possible terminating newline) in a (1-based) numbered line. - */ - public final String getCode(int lineNumber) { - final int offset = getTextMap().lineStartOffset(lineNumber); - final int length = getTextMap().lineLength(lineNumber); - return getCode().substring(offset, offset + length); - } - - /** - * The number of text lines in the source, including empty lines; characters at the end of the - * source without a terminating newline count as a line. - */ - public final int getLineCount() { - return getTextMap().lineCount(); - } - - /** - * Given a 0-based character offset, return the 1-based number of the line that includes the - * position. - * - * @throws IllegalArgumentException if the offset is outside the text contents - */ - public final int getLineNumber(int offset) throws IllegalArgumentException { - return getTextMap().offsetToLine(offset); - } - - /** - * Given a 0-based character offset, return the 1-based number of the column at the position. - * - * @throws IllegalArgumentException if the offset is outside the text contents - */ - public final int getColumnNumber(int offset) throws IllegalArgumentException { - return getTextMap().offsetToCol(offset); - } - - /** - * Given a 1-based line number, return the 0-based offset of the first character in the line. - * - * @throws IllegalArgumentException if there is no such line in the text - */ - public final int getLineStartOffset(int lineNumber) throws IllegalArgumentException { - return getTextMap().lineStartOffset(lineNumber); - } - - /** - * The number of characters (not counting a possible terminating newline) in a (1-based) - * numbered line. - * - * @throws IllegalArgumentException if there is no such line in the text - */ - public final int getLineLength(int lineNumber) throws IllegalArgumentException { - return getTextMap().lineLength(lineNumber); - } - - /** - * Append text to a Source explicitly created as Appendable. - * - * @param chars the text to append - * @throws UnsupportedOperationException by concrete subclasses that do not support appending - */ - public void appendCode(CharSequence chars) { - throw new UnsupportedOperationException(); - } - - /** - * Creates a representation of a contiguous region of text in the source. - *

- * This method performs no checks on the validity of the arguments. - *

- * The resulting representation defines hash/equality around equivalent location, presuming that - * {@link Source} representations are canonical. - * - * @param identifier terse description of the region - * @param startLine 1-based line number of the first character in the section - * @param startColumn 1-based column number of the first character in the section - * @param charIndex the 0-based index of the first character of the section - * @param length the number of characters in the section - * @return newly created object representing the specified region - */ - public final SourceSection createSection(String identifier, int startLine, int startColumn, int charIndex, int length) { - return new DefaultSourceSection(this, identifier, startLine, startColumn, charIndex, length); - } - - /** - * Creates a representation of a contiguous region of text in the source. Computes the - * {@code charIndex} value by building a {@linkplain TextMap map} of lines in the source. - *

- * Checks the position arguments for consistency with the source. - *

- * The resulting representation defines hash/equality around equivalent location, presuming that - * {@link Source} representations are canonical. - * - * @param identifier terse description of the region - * @param startLine 1-based line number of the first character in the section - * @param startColumn 1-based column number of the first character in the section - * @param length the number of characters in the section - * @return newly created object representing the specified region - * @throws IllegalArgumentException if arguments are outside the text of the source - * @throws IllegalStateException if the source is one of the "null" instances - */ - public final SourceSection createSection(String identifier, int startLine, int startColumn, int length) { - final int lineStartOffset = getTextMap().lineStartOffset(startLine); - if (startColumn > getTextMap().lineLength(startLine)) { - throw new IllegalArgumentException("column out of range"); - } - final int startOffset = lineStartOffset + startColumn - 1; - return new DefaultSourceSection(this, identifier, startLine, startColumn, startOffset, length); - } - - /** - * Creates a representation of a contiguous region of text in the source. Computes the - * {@code (startLine, startColumn)} values by building a {@linkplain TextMap map} of lines in - * the source. - *

- * Checks the position arguments for consistency with the source. - *

- * The resulting representation defines hash/equality around equivalent location, presuming that - * {@link Source} representations are canonical. - * - * - * @param identifier terse description of the region - * @param charIndex 0-based position of the first character in the section - * @param length the number of characters in the section - * @return newly created object representing the specified region - * @throws IllegalArgumentException if either of the arguments are outside the text of the - * source - * @throws IllegalStateException if the source is one of the "null" instances - */ - public final SourceSection createSection(String identifier, int charIndex, int length) throws IllegalArgumentException { - checkRange(charIndex, length); - final int startLine = getLineNumber(charIndex); - final int startColumn = charIndex - getLineStartOffset(startLine) + 1; - return new DefaultSourceSection(this, identifier, startLine, startColumn, charIndex, length); - } - - protected void checkRange(int charIndex, int length) { - if (!(charIndex >= 0 && length >= 0 && charIndex + length <= getCode().length())) { - throw new IllegalArgumentException("text positions out of range"); - } - } - - /** - * Creates a representation of a line of text in the source identified only by line number, from - * which the character information will be computed. - * - * @param identifier terse description of the line - * @param lineNumber 1-based line number of the first character in the section - * @return newly created object representing the specified line - * @throws IllegalArgumentException if the line does not exist the source - * @throws IllegalStateException if the source is one of the "null" instances - */ - public final SourceSection createSection(String identifier, int lineNumber) { - final int charIndex = getTextMap().lineStartOffset(lineNumber); - final int length = getTextMap().lineLength(lineNumber); - return createSection(identifier, charIndex, length); - } - - /** - * Creates a representation of a line number in this source, suitable for use as a hash table - * key with equality defined to mean equivalent location. - * - * @param lineNumber a 1-based line number in this source - * @return a representation of a line in this source - */ - public final LineLocation createLineLocation(int lineNumber) { - return new LineLocationImpl(this, lineNumber); - } - - /** - * An object suitable for using as a key into a hashtable that defines equivalence between - * different source types. - */ - protected Object getHashKey() { - return getName(); - } - - protected final TextMap getTextMap() { - if (textMap == null) { - textMap = createTextMap(); - } - return textMap; - } - - protected final void clearTextMap() { - textMap = null; - } - - protected TextMap createTextMap() { - final String code = getCode(); - if (code == null) { - throw new RuntimeException("can't read file " + getName()); - } - return TextMap.fromString(code); - } - - private static final class LiteralSource extends Source { - - private final String description; - private final String code; - - public LiteralSource(String description, String code) { - this.description = description; - this.code = code; - } - - @Override - public String getName() { - return description; - } - - @Override - public String getShortName() { - return description; - } - - @Override - public String getCode() { - return code; - } - - @Override - public String getPath() { - return description; - } - - @Override - public URL getURL() { - return null; - } - - @Override - public Reader getReader() { - return new StringReader(code); - } - - @Override - protected void reset() { - } - - @Override - public int hashCode() { - return description.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (obj instanceof LiteralSource) { - LiteralSource other = (LiteralSource) obj; - return description.equals(other.description); - } - return false; - } - } - - private static final class AppendableLiteralSource extends Source { - private String description; - final List codeList = new ArrayList<>(); - - public AppendableLiteralSource(String description) { - this.description = description; - } - - @Override - public String getName() { - return description; - } - - @Override - public String getShortName() { - return description; - } - - @Override - public String getCode() { - return getCodeFromIndex(0); - } - - @Override - public String getPath() { - return description; - } - - @Override - public URL getURL() { - return null; - } - - @Override - public Reader getReader() { - return new StringReader(getCode()); - } - - @Override - protected void reset() { - } - - private String getCodeFromIndex(int index) { - StringBuilder sb = new StringBuilder(); - for (int i = index; i < codeList.size(); i++) { - CharSequence s = codeList.get(i); - sb.append(s); - } - return sb.toString(); - } - - @Override - public void appendCode(CharSequence chars) { - codeList.add(chars); - clearTextMap(); - } - - } - - private static final class FileSource extends Source { - - private final File file; - private final String name; // Name used originally to describe the source - private final String path; // Normalized path description of an actual file - - private String code = null; // A cache of the file's contents - private long timeStamp; // timestamp of the cache in the file system - - public FileSource(File file, String name, String path) { - this(file, name, path, null); - } - - public FileSource(File file, String name, String path, CharSequence chars) { - this.file = file.getAbsoluteFile(); - this.name = name; - this.path = path; - if (chars != null) { - this.code = chars.toString(); - } - } - - @Override - public String getName() { - return name; - } - - @Override - public String getShortName() { - return file.getName(); - } - - @Override - protected Object getHashKey() { - return path; - } - - @Override - public String getCode() { - if (fileCacheEnabled) { - if (code == null || timeStamp != file.lastModified()) { - try { - code = read(getReader()); - timeStamp = file.lastModified(); - } catch (IOException e) { - } - } - return code; - } - try { - return read(new FileReader(file)); - } catch (IOException e) { - } - return null; - } - - @Override - public String getPath() { - return path; - } - - @Override - public URL getURL() { - return null; - } - - @Override - public Reader getReader() { - if (code != null && timeStamp == file.lastModified()) { - return new StringReader(code); - } - try { - return new FileReader(file); - } catch (FileNotFoundException e) { - - throw new RuntimeException("Can't find file " + path, e); - } - } - - @Override - public int hashCode() { - return path.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof FileSource) { - FileSource other = (FileSource) obj; - return path.equals(other.path); - } - return false; - } - - @Override - protected void reset() { - this.code = null; - } - } - - private static final class URLSource extends Source { - - private static final Map> urlToSource = new HashMap<>(); - - public static URLSource get(URL url, String name) throws IOException { - WeakReference sourceRef = urlToSource.get(url); - URLSource source = sourceRef == null ? null : sourceRef.get(); - if (source == null) { - source = new URLSource(url, name); - urlToSource.put(url, new WeakReference<>(source)); - } - return source; - } - - private final URL url; - private final String name; - private String code = null; // A cache of the source contents - - public URLSource(URL url, String name) throws IOException { - this.url = url; - this.name = name; - code = read(new InputStreamReader(url.openStream())); - } - - @Override - public String getName() { - return name; - } - - @Override - public String getShortName() { - return name; - } - - @Override - public String getPath() { - return url.getPath(); - } - - @Override - public URL getURL() { - return url; - } - - @Override - public Reader getReader() { - return new StringReader(code); - } - - @Override - public String getCode() { - return code; - } - - @Override - protected void reset() { - } - } - - private static final class SubSource extends Source { - private final Source base; - private final int baseIndex; - private final int subLength; - - private static SubSource create(Source base, int baseIndex, int length) { - if (baseIndex < 0 || length < 0 || baseIndex + length > base.getLength()) { - throw new IllegalArgumentException("text positions out of range"); - } - return new SubSource(base, baseIndex, length); - } - - private SubSource(Source base, int baseIndex, int length) { - this.base = base; - this.baseIndex = baseIndex; - this.subLength = length; - } - - @Override - protected void reset() { - assert false; - } - - @Override - public String getName() { - return base.getName(); - } - - @Override - public String getShortName() { - return base.getShortName(); - } - - @Override - public String getPath() { - return base.getPath(); - } - - @Override - public URL getURL() { - return null; - } - - @Override - public Reader getReader() { - assert false; - return null; - } - - @Override - public String getCode() { - return base.getCode(baseIndex, subLength); - } - } - - private static final class BytesSource extends Source { - - private final String name; - private final byte[] bytes; - private final int byteIndex; - private final int length; - private final BytesDecoder decoder; - - public BytesSource(String name, byte[] bytes, int byteIndex, int length, BytesDecoder decoder) { - this.name = name; - this.bytes = bytes; - this.byteIndex = byteIndex; - this.length = length; - this.decoder = decoder; - } - - @Override - protected void reset() { - } - - @Override - public String getName() { - return name; - } - - @Override - public String getShortName() { - return name; - } - - @Override - public String getPath() { - return name; - } - - @Override - public URL getURL() { - return null; - } - - @Override - public Reader getReader() { - return null; - } - - @Override - public String getCode() { - return decoder.decode(bytes, byteIndex, length); - } - - @Override - public String getCode(int byteOffset, int codeLength) { - return decoder.decode(bytes, byteIndex + byteOffset, codeLength); - } - - @Override - protected void checkRange(int charIndex, int rangeLength) { - if (!(charIndex >= 0 && rangeLength >= 0 && charIndex + rangeLength <= length)) { - throw new IllegalArgumentException("text positions out of range"); - } - } - - @Override - protected TextMap createTextMap() { - return TextMap.fromBytes(bytes, byteIndex, length, decoder); - } - } - - private static final class DefaultSourceSection implements SourceSection { - - private final Source source; - private final String identifier; - private final int startLine; - private final int startColumn; - private final int charIndex; - private final int charLength; - - /** - * Creates a new object representing a contiguous text section within the source code of a - * guest language program's text. - *

- * The starting location of the section is specified using two different coordinate: - *

    - *
  • (row, column): rows and columns are 1-based, so the first character in a - * source file is at position {@code (1,1)}.
  • - *
  • character index: 0-based offset of the character from the beginning of the - * source, so the first character in a file is at index {@code 0}.
  • - *
- * The newline that terminates each line counts as a single character for the purpose - * of a character index. The (row,column) coordinates of a newline character should never - * appear in a text section. - *

- * - * @param source object representing the complete source program that contains this section - * @param identifier an identifier used when printing the section - * @param startLine the 1-based number of the start line of the section - * @param startColumn the 1-based number of the start column of the section - * @param charIndex the 0-based index of the first character of the section - * @param charLength the length of the section in number of characters - */ - public DefaultSourceSection(Source source, String identifier, int startLine, int startColumn, int charIndex, int charLength) { - this.source = source; - this.identifier = identifier; - this.startLine = startLine; - this.startColumn = startColumn; - this.charIndex = charIndex; - this.charLength = charLength; - } - - @Override - public Source getSource() { - return source; - } - - @Override - public int getStartLine() { - return startLine; - } - - @Override - public LineLocation getLineLocation() { - return source.createLineLocation(startLine); - } - - @Override - public int getStartColumn() { - return startColumn; - } - - public int getEndLine() { - return source.getLineNumber(charIndex + charLength - 1); - } - - public int getEndColumn() { - return source.getColumnNumber(charIndex + charLength - 1); - } - - @Override - public int getCharIndex() { - return charIndex; - } - - @Override - public int getCharLength() { - return charLength; - } - - @Override - public int getCharEndIndex() { - return charIndex + charLength; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getCode() { - return getSource().getCode(charIndex, charLength); - } - - @Override - public String getShortDescription() { - return String.format("%s:%d", source.getShortName(), startLine); - } - - @Override - public String toString() { - return getCode(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + charIndex; - result = prime * result + charLength; - result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); - result = prime * result + ((source == null) ? 0 : source.hashCode()); - result = prime * result + startColumn; - result = prime * result + startLine; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof DefaultSourceSection)) { - return false; - } - DefaultSourceSection other = (DefaultSourceSection) obj; - if (charIndex != other.charIndex) { - return false; - } - if (charLength != other.charLength) { - return false; - } - if (identifier == null) { - if (other.identifier != null) { - return false; - } - } else if (!identifier.equals(other.identifier)) { - return false; - } - if (source == null) { - if (other.source != null) { - return false; - } - } else if (!source.equals(other.source)) { - return false; - } - if (startColumn != other.startColumn) { - return false; - } - if (startLine != other.startLine) { - return false; - } - return true; - } - } - - private static final class LineLocationImpl implements LineLocation { - private final Source source; - private final int line; - - public LineLocationImpl(Source source, int line) { - assert source != null; - this.source = source; - this.line = line; - } - - @Override - public Source getSource() { - return source; - } - - @Override - public int getLineNumber() { - return line; - } - - @Override - public String getShortDescription() { - return source.getShortName() + ":" + line; - } - - @Override - public String toString() { - return "Line[" + getShortDescription() + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + line; - result = prime * result + source.getHashKey().hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof LineLocationImpl)) { - return false; - } - LineLocationImpl other = (LineLocationImpl) obj; - if (line != other.line) { - return false; - } - return source.getHashKey().equals(other.source.getHashKey()); - } - - } - - /** - * A utility for converting between coordinate systems in a string of text interspersed with - * newline characters. The coordinate systems are: - *

    - *
  • 0-based character offset from the beginning of the text, where newline characters count - * as a single character and the first character in the text occupies position 0.
  • - *
  • 1-based position in the 2D space of lines and columns, in which the first position in the - * text is at (1,1).
  • - *
- *

- * This utility is based on positions occupied by characters, not text stream positions as in a - * text editor. The distinction shows up in editors where you can put the cursor just past the - * last character in a buffer; this is necessary, among other reasons, so that you can put the - * edit cursor in a new (empty) buffer. For the purposes of this utility, however, there are no - * character positions in an empty text string and there are no lines in an empty text string. - *

- * A newline character designates the end of a line and occupies a column position. - *

- * If the text ends with a character other than a newline, then the characters following the - * final newline character count as a line, even though not newline-terminated. - *

- * Limitations: - *

    - *
  • Does not handle multiple character encodings correctly.
  • - *
  • Treats tabs as occupying 1 column.
  • - *
  • Does not handle multiple-character line termination sequences correctly.
  • - *
- */ - private static final class TextMap { - - // 0-based offsets of newline characters in the text, with sentinel - private final int[] nlOffsets; - - // The number of characters in the text, including newlines (which count as 1). - private final int textLength; - - // Is the final text character a newline? - final boolean finalNL; - - public TextMap(int[] nlOffsets, int textLength, boolean finalNL) { - this.nlOffsets = nlOffsets; - this.textLength = textLength; - this.finalNL = finalNL; - } - - /** - * Constructs map permitting translation between 0-based character offsets and 1-based - * lines/columns. - */ - public static TextMap fromString(String text) { - final int textLength = text.length(); - final ArrayList lines = new ArrayList<>(); - lines.add(0); - int offset = 0; - - while (offset < text.length()) { - final int nlIndex = text.indexOf('\n', offset); - if (nlIndex >= 0) { - offset = nlIndex + 1; - lines.add(offset); - } else { - break; - } - } - lines.add(Integer.MAX_VALUE); - - final int[] nlOffsets = new int[lines.size()]; - for (int line = 0; line < lines.size(); line++) { - nlOffsets[line] = lines.get(line); - } - - final boolean finalNL = textLength > 0 && (textLength == nlOffsets[nlOffsets.length - 2]); - - return new TextMap(nlOffsets, textLength, finalNL); - } - - public static TextMap fromBytes(byte[] bytes, int byteIndex, int length, BytesDecoder bytesDecoder) { - final ArrayList lines = new ArrayList<>(); - lines.add(0); - - bytesDecoder.decodeLines(bytes, byteIndex, length, new BytesDecoder.LineMarker() { - - public void markLine(int index) { - lines.add(index); - } - }); - - lines.add(Integer.MAX_VALUE); - - final int[] nlOffsets = new int[lines.size()]; - for (int line = 0; line < lines.size(); line++) { - nlOffsets[line] = lines.get(line); - } - - final boolean finalNL = length > 0 && (length == nlOffsets[nlOffsets.length - 2]); - - return new TextMap(nlOffsets, length, finalNL); - } - - /** - * Converts 0-based character offset to 1-based number of the line containing the character. - * - * @throws IllegalArgumentException if the offset is outside the string. - */ - public int offsetToLine(int offset) throws IllegalArgumentException { - if (offset < 0 || offset >= textLength) { - throw new IllegalArgumentException("offset out of bounds"); - } - int line = 1; - while (offset >= nlOffsets[line]) { - line++; - } - return line; - } - - /** - * Converts 0-based character offset to 1-based number of the column occupied by the - * character. - *

- * Tabs are not expanded; they occupy 1 column. - * - * @throws IllegalArgumentException if the offset is outside the string. - */ - public int offsetToCol(int offset) throws IllegalArgumentException { - return 1 + offset - nlOffsets[offsetToLine(offset) - 1]; - } - - /** - * The number of characters in the mapped text. - */ - public int length() { - return textLength; - } - - /** - * The number of lines in the text; if characters appear after the final newline, then they - * also count as a line, even though not newline-terminated. - */ - public int lineCount() { - if (textLength == 0) { - return 0; - } - return finalNL ? nlOffsets.length - 2 : nlOffsets.length - 1; - } - - /** - * Converts 1-based line number to the 0-based offset of the line's first character; this - * would be the offset of a newline if the line is empty. - * - * @throws IllegalArgumentException if there is no such line in the text. - */ - public int lineStartOffset(int line) throws IllegalArgumentException { - if (textLength == 0 || lineOutOfRange(line)) { - throw new IllegalArgumentException("line out of bounds"); - } - return nlOffsets[line - 1]; - } - - /** - * Gets the number of characters in a line, identified by 1-based line number; - * does not include the final newline, if any. - * - * @throws IllegalArgumentException if there is no such line in the text. - */ - public int lineLength(int line) throws IllegalArgumentException { - if (textLength == 0 || lineOutOfRange(line)) { - throw new IllegalArgumentException("line out of bounds"); - } - if (line == nlOffsets.length - 1 && !finalNL) { - return textLength - nlOffsets[line - 1]; - } - return (nlOffsets[line] - nlOffsets[line - 1]) - 1; - - } - - /** - * Is the line number out of range. - */ - private boolean lineOutOfRange(int line) { - return line <= 0 || line >= nlOffsets.length || (line == nlOffsets.length - 1 && finalNL); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * An observer of events related to {@link Source}s: creating and tagging. - */ -public interface SourceListener { - - /** - * Notifies that a new {@link Source} has just been created. - */ - void sourceCreated(Source source); - - /** - * Notifies that a {@link SourceTag} has been newly added to the set of tags associated with a - * {@link Source} via {@link Source#tagAs(SourceTag)}. - *

- * The {@linkplain SourceTag tags} at a {@link Source} are a set; this notification - * will only be delivered the first time a particular {@linkplain SourceTag tag} is added at a - * {@link Source}. - * - * @param source where a tag has been added - * @param tag the tag that has been newly added (subsequent additions of the tag are - * unreported). - */ - void sourceTaggedAs(Source source, SourceTag tag); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceSection.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceSection.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Description of contiguous section of text within a {@link Source} of program code; supports - * multiple modes of access to the text and its location. A special {@linkplain NullSourceSection - * null subtype} should be used for code that is not available from source, e.g language builtins. - * - * @see Source#createSection(String, int, int, int, int) - * @see Source#createSection(String, int, int, int) - * @see Source#createSection(String, int, int) - * @see Source#createSection(String, int) - * @see NullSourceSection - */ -public interface SourceSection { - - // TODO support alternate text representations/encodings - - /** - * Representation of the source program that contains this section. - * - * @return the source object - */ - Source getSource(); - - /** - * Returns 1-based line number of the first character in this section (inclusive). - * - * @return the starting line number - */ - int getStartLine(); - - /** - * Gets a representation of the first line of the section, suitable for a hash key. - */ - LineLocation getLineLocation(); - - /** - * Returns the 1-based column number of the first character in this section (inclusive). - * - * @return the starting column number - */ - int getStartColumn(); - - /** - * Returns 1-based line number of the last character in this section (inclusive). - * - * @return the starting line number - */ - int getEndLine(); - - /** - * Returns the 1-based column number of the last character in this section (inclusive). - * - * @return the starting column number - */ - int getEndColumn(); - - /** - * Returns the 0-based index of the first character in this section. - * - * @return the starting character index - */ - int getCharIndex(); - - /** - * Returns the length of this section in characters. - * - * @return the number of characters in the section - */ - int getCharLength(); - - /** - * Returns the index of the text position immediately following the last character in the - * section. - * - * @return the end position of the section - */ - int getCharEndIndex(); - - /** - * Returns terse text describing this source section, typically used for printing the section. - * - * @return the identifier of the section - */ - String getIdentifier(); - - /** - * Returns text described by this section. - * - * @return the code as a String object - */ - String getCode(); - - /** - * Returns a short description of the source section, using just the file name, rather than its - * full path. - * - * @return a short description of the source section - */ - String getShortDescription(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceTag.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceTag.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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; - -/** - * Categorical information (best implemented as enums} about particular sources of Guest Language - * code that can be useful to configure behavior of both the language runtime and external tools. - * These might include {@linkplain Source.Tags standard tags} noting, for example, whether the - * source was read from a file and whether it should be considered library code. - *

- * The need for additional tags is likely to arise, in some cases because of issue specific to a - * Guest Language, but also for help configuring the behavior of particular tools. - * - * @see Source - * @see Source.Tags - */ -public interface SourceTag { - - /** - * Human-friendly name of a category of code sources, e.g. "file", or "library". - * - */ - String name(); - - /** - * Criteria and example uses for the tag. - */ - String getDescription(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/unsafe/UnsafeAccess.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/unsafe/UnsafeAccess.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,266 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.unsafe; - -public interface UnsafeAccess { - - /** - * Casts the given value to the value of the given type without any checks. The class must - * evaluate to a constant. The condition parameter gives a hint to the compiler under which - * circumstances this cast can be moved to an earlier location in the program. - * - * @param value the value that is known to have the specified type - * @param type the specified new type of the value - * @param condition the condition that makes this cast safe also at an earlier location of the - * program - * @param nonNull whether value is known to never be null - * @return the value to be casted to the new type - */ - T uncheckedCast(Object value, Class type, boolean condition, boolean nonNull); - - /** - * Unsafe access to a boolean value within an object. The condition parameter gives a hint to - * the compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - boolean getBoolean(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to a byte value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - byte getByte(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to a short value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - short getShort(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to an int value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - int getInt(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to a long value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - long getLong(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to a float value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - float getFloat(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to a double value within an object. The condition parameter gives a hint to the - * compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - double getDouble(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Unsafe access to an Object value within an object. The condition parameter gives a hint to - * the compiler under which circumstances this access can be moved to an earlier location in the - * program. The location identity gives a hint to the compiler for improved global value - * numbering. - * - * @param receiver the object that is accessed - * @param offset the offset at which to access the object in bytes - * @param condition the condition that makes this access safe also at an earlier location in the - * program - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - * @return the accessed value - */ - Object getObject(Object receiver, long offset, boolean condition, Object locationIdentity); - - /** - * Write a boolean value within an object. The location identity gives a hint to the compiler - * for improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putBoolean(Object receiver, long offset, boolean value, Object locationIdentity); - - /** - * Write a byte value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putByte(Object receiver, long offset, byte value, Object locationIdentity); - - /** - * Write a short value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putShort(Object receiver, long offset, short value, Object locationIdentity); - - /** - * Write an int value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putInt(Object receiver, long offset, int value, Object locationIdentity); - - /** - * Write a long value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putLong(Object receiver, long offset, long value, Object locationIdentity); - - /** - * Write a float value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putFloat(Object receiver, long offset, float value, Object locationIdentity); - - /** - * Write a double value within an object. The location identity gives a hint to the compiler for - * improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putDouble(Object receiver, long offset, double value, Object locationIdentity); - - /** - * Write an Object value within an object. The location identity gives a hint to the compiler - * for improved global value numbering. - * - * @param receiver the object that is written to - * @param offset the offset at which to write to the object in bytes - * @param value the value to be written - * @param locationIdentity the location identity token that can be used for improved global - * value numbering or null - */ - void putObject(Object receiver, long offset, Object value, Object locationIdentity); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/unsafe/UnsafeAccessFactory.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/unsafe/UnsafeAccessFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.unsafe; - -import sun.misc.*; - -public interface UnsafeAccessFactory { - UnsafeAccess createUnsafeAccess(Unsafe unsafe); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/AlwaysValidAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/AlwaysValidAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.nodes.*; - -/** - * An assumption that is always valid. Used as a placeholder where an assumption is needed but never - * invalidated. - */ -public final class AlwaysValidAssumption implements Assumption { - - public static final AlwaysValidAssumption INSTANCE = new AlwaysValidAssumption(); - - private AlwaysValidAssumption() { - } - - @Override - public void check() throws InvalidAssumptionException { - } - - @Override - public void invalidate() { - throw new UnsupportedOperationException("Cannot invalidate this assumption - it is always valid"); - } - - @Override - public String getName() { - return getClass().getName(); - } - - @Override - public boolean isValid() { - return true; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/AssumedValue.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/AssumedValue.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.nodes.*; - -/** - * A value that the compiler can assume is constant, but can be changed by invalidation. - *

- * Compiled code that uses the value will be invalidated each time the value changes, so you should - * take care to only change values infrequently, or to monitor the number of times the value has - * changed and at some point to replace the value with something more generic so that it does not - * have to be changed and code does not have to keep being recompiled. - */ -public class AssumedValue { - - private final String name; - - @CompilationFinal private T value; - @CompilationFinal private Assumption assumption; - - public AssumedValue(T initialValue) { - this(null, initialValue); - } - - public AssumedValue(String name, T initialValue) { - this.name = name; - value = initialValue; - assumption = Truffle.getRuntime().createAssumption(name); - } - - /** - * Get the current value, updating it if it has been {@link #set}. The compiler may be able to - * make this method return a constant value, but still accommodate mutation. - */ - public T get() { - try { - assumption.check(); - } catch (InvalidAssumptionException e) { - // No need to rewrite anything - just pick up the new values - } - - return value; - } - - /** - * Set a new value, which will be picked up the next time {@link #get} is called. - */ - public void set(T newValue) { - CompilerDirectives.transferToInterpreter(); - - value = newValue; - final Assumption oldAssumption = assumption; - assumption = Truffle.getRuntime().createAssumption(name); - oldAssumption.invalidate(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * Utility class to speculate on conditions to be never true or to be never false. Condition - * profiles are intended to be used as part of if conditions. - * - * @see ConditionProfile#createBinaryProfile() - */ -public final class BinaryConditionProfile extends ConditionProfile { - - @CompilationFinal private boolean wasTrue; - @CompilationFinal private boolean wasFalse; - - BinaryConditionProfile() { - /* package protected constructor */ - } - - @Override - public boolean profile(boolean value) { - if (value) { - if (!wasTrue) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - wasTrue = true; - } - return true; - } else { - if (!wasFalse) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - wasFalse = true; - } - return false; - } - } - - public boolean wasTrue() { - return wasTrue; - } - - public boolean wasFalse() { - return wasFalse; - } - - @Override - public String toString() { - return String.format("%s(wasTrue=%s, wasFalse=%s)@%x", getClass().getSimpleName(), wasTrue, wasFalse, hashCode()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.nodes.*; - -/** - * Utility class to speculate on branches to be never visited. If the {@link #enter()} method is - * invoked first the optimized code is invalidated and the branch where {@link #enter()} is invoked - * is enabled for compilation. Otherwise if the {@link #enter()} method was never invoked the branch - * will not get compiled. - * - * All {@code BranchProfile} instances must be held in {@code final} fields for compiler - * optimizations to take effect. - */ -public final class BranchProfile extends NodeCloneable { - - @CompilationFinal private boolean visited; - - private BranchProfile() { - } - - public void enter() { - if (!visited) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - visited = true; - } - } - - public boolean isVisited() { - return visited; - } - - public static BranchProfile create() { - return new BranchProfile(); - } - - @Override - public String toString() { - return String.format("%s(%s)@%x", getClass().getSimpleName(), visited ? "visited" : "not-visited", hashCode()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Abstract utility class to speculate on conditions. Condition profiles are intended to be used as - * part of if conditions. - * - * Example usage: - * - *

- * private final ConditionProfile zero = ConditionProfile.createBinaryProfile();
- *
- * int value = ...;
- * if (zero.profile(value == 0)) {
- *   return 0;
- * } else {
- *   return value;
- * }
- *
- * 
- * - * All instances of {@code ConditionProfile} (and subclasses) must be held in {@code final} fields - * for compiler optimizations to take effect. - * - * @see #createCountingProfile() - * @see #createBinaryProfile() - */ -public abstract class ConditionProfile extends NodeCloneable { - ConditionProfile() { - } - - public abstract boolean profile(boolean value); - - /** - * Returns a {@link ConditionProfile} that speculates on conditions to be never - * true or to be never false. Additionally to a binary profile this - * method returns a condition profile that also counts the number of times the condition was - * true and false. This information is reported to the underlying optimization system using - * {@link CompilerDirectives#injectBranchProbability(double, boolean)}. Condition profiles are - * intended to be used as part of if conditions. - * - * @see ConditionProfile - * @see #createBinaryProfile() - */ - public static ConditionProfile createCountingProfile() { - return new CountingConditionProfile(); - } - - /** - * Returns a {@link ConditionProfile} that speculates on conditions to be never true or to be - * never false. Condition profiles are intended to be used as part of if conditions. - * - * @see ConditionProfile - * @see ConditionProfile#createCountingProfile() - */ - public static ConditionProfile createBinaryProfile() { - return new BinaryConditionProfile(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CountingConditionProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CountingConditionProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * Utility class to speculate on conditions to be never true or to be never false. Additionally to - * {@link BinaryConditionProfile} this implementation of {@link ConditionProfile} also counts the - * number of times the condition was true and false. This information is reported to the underlying - * optimization system using {@link CompilerDirectives#injectBranchProbability(double, boolean)}. - * Condition profiles are intended to be used as part of if conditions. - * - * @see ConditionProfile#createCountingProfile() - */ -public final class CountingConditionProfile extends ConditionProfile { - - @CompilationFinal private int trueCount; - @CompilationFinal private int falseCount; - - CountingConditionProfile() { - /* package protected constructor */ - } - - @Override - public boolean profile(boolean value) { - if (value) { - if (trueCount == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - } - if (CompilerDirectives.inInterpreter()) { - trueCount++; - } - } else { - if (falseCount == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - } - if (CompilerDirectives.inInterpreter()) { - falseCount++; - } - } - return CompilerDirectives.injectBranchProbability((double) trueCount / (double) (trueCount + falseCount), value); - } - - public int getTrueCount() { - return trueCount; - } - - public int getFalseCount() { - return falseCount; - } - - @Override - public String toString() { - return String.format("%s(trueCount=%s, falseCount=%s)@%x", getClass().getSimpleName(), trueCount, falseCount, hashCode()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CyclicAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CyclicAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.util.concurrent.atomic.*; - -import com.oracle.truffle.api.*; - -/** - * Holds an {@link Assumption}, and knows how to recreate it with the same properties on - * invalidation. Used so that mutability is isolated in this class, and all other classes that need - * an assumption that may be recreated can have a final reference to an object of this class. Note - * that you should be careful that repeated invalidations do not cause a deoptimization loop in that - * same way that you would with any other assumption. - */ -public class CyclicAssumption { - - private final String name; - private final AtomicReference assumption; - - public CyclicAssumption(String name) { - this.name = name; - this.assumption = new AtomicReference<>(Truffle.getRuntime().createAssumption(name)); - } - - public void invalidate() { - Assumption newAssumption = Truffle.getRuntime().createAssumption(name); - Assumption oldAssumption = assumption.getAndSet(newAssumption); - oldAssumption.invalidate(); - } - - public Assumption getAssumption() { - return assumption.get(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * Represents a {@link ValueProfile} that speculates on the exact class of a value. - */ -public final class ExactClassValueProfile extends ValueProfile { - - @CompilationFinal protected Class cachedClass; - - ExactClassValueProfile() { - } - - @SuppressWarnings("unchecked") - @Override - public T profile(T value) { - if (cachedClass != Object.class) { - if (cachedClass != null && cachedClass.isInstance(value)) { - return (T) cachedClass.cast(value); - } else { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (cachedClass == null && value != null) { - cachedClass = value.getClass(); - } else { - cachedClass = Object.class; - } - } - } - return value; - } - - public boolean isGeneric() { - return cachedClass == Object.class; - } - - public boolean isUninitialized() { - return cachedClass == null; - } - - public Class getCachedClass() { - return cachedClass; - } - - @Override - public String toString() { - return String.format("%s(%s)@%x", getClass().getSimpleName(), isUninitialized() ? "uninitialized" : (isGeneric() ? "generic" : cachedClass.getName()), hashCode()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/IdentityValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/IdentityValueProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * Represents a {@link ValueProfile} that speculates on the object identity of a value. - */ -public final class IdentityValueProfile extends ValueProfile { - - private static final Object UNINITIALIZED = new Object(); - private static final Object GENERIC = new Object(); - - @CompilationFinal protected Object cachedValue = UNINITIALIZED; - - IdentityValueProfile() { - } - - @Override - @SuppressWarnings("unchecked") - public T profile(T value) { - if (cachedValue != GENERIC) { - if (cachedValue == value) { - return (T) cachedValue; - } else { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (cachedValue == UNINITIALIZED) { - cachedValue = value; - } else { - cachedValue = GENERIC; - } - } - } - return value; - } - - public boolean isGeneric() { - return getCachedValue() == GENERIC; - } - - public boolean isUninitialized() { - return getCachedValue() == UNINITIALIZED; - } - - public Object getCachedValue() { - return cachedValue; - } - - @Override - public String toString() { - return String.format("%s(%s)@%x", getClass().getSimpleName(), isUninitialized() ? "uninitialized" : (isGeneric() ? "generic" : String.format("@%x", Objects.hash(cachedValue))), hashCode()); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.util.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Helper function that allows to dump the AST during creation to a JSON format. - */ -public class JSONHelper { - - private static StringBuilder AstJsonDumpBuilder = new StringBuilder(); - - public static void dumpNewChild(Node parentNode, Node childNode) { - if (AstJsonDumpBuilder != null) { - AstJsonDumpBuilder.append("{ \"action\": \"insertNode\", \"parentId\": \"" + getID(parentNode) + "\", \"newId\": \"" + getID(childNode) + "\" },\n"); - } - } - - public static void dumpReplaceChild(Node oldNode, Node newNode, CharSequence reason) { - if (AstJsonDumpBuilder != null) { - AstJsonDumpBuilder.append("{ \"action\": \"replaceNode\", \"oldId\": \"" + getID(oldNode) + "\", \"newId\": \"" + getID(newNode) + "\", \"reason\": " + quote(reason) + " },\n"); - } - } - - public static void dumpNewNode(Node newNode) { - if (AstJsonDumpBuilder != null) { - AstJsonDumpBuilder.append("{ \"action\": \"createNode\", \"newId\": \"" + getID(newNode) + "\", \"type\": \"" + getType(newNode) + "\", \"description\": \"" + newNode.getDescription() + - "\", \"language\": \"" + newNode.getLanguage() + "\"" + getSourceSectionInfo(newNode) + " },\n"); - } - } - - private static String getSourceSectionInfo(Node newNode) { - SourceSection sourceSection = newNode.getSourceSection(); - if (sourceSection != null) { - return ", \"identifier\": \"" + sourceSection.getIdentifier() + "\" "; - } else { - return ""; - } - } - - public static String getResult() { - return AstJsonDumpBuilder.toString(); - } - - private static String getID(Node newChild) { - return String.valueOf(newChild.hashCode()); - } - - private static String getType(Node node) { - return node.getClass().getSimpleName(); - } - - private static String quote(CharSequence value) { - StringBuilder builder = new StringBuilder(value.length() + 2); - builder.append('"'); - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - switch (c) { - case '"': - builder.append("\\\""); - break; - case '\\': - builder.append("\\\\"); - break; - case '\b': - builder.append("\\b"); - break; - case '\f': - builder.append("\\f"); - break; - case '\n': - builder.append("\\n"); - break; - case '\r': - builder.append("\\r"); - break; - case '\t': - builder.append("\\t"); - break; - default: { - if (c < ' ') { - builder.append("\\u00"); - builder.append(Character.forDigit((c >> 4) & 0xF, 16)); - builder.append(Character.forDigit(c & 0xF, 16)); - } else { - builder.append(c); - } - } - } - } - builder.append('"'); - return builder.toString(); - } - - public static void restart() { - AstJsonDumpBuilder = new StringBuilder(); - } - - public static JSONObjectBuilder object() { - return new JSONObjectBuilder(); - } - - public static JSONArrayBuilder array() { - return new JSONArrayBuilder(); - } - - public abstract static class JSONStringBuilder { - @Override - public final String toString() { - StringBuilder sb = new StringBuilder(); - appendTo(sb); - return sb.toString(); - } - - protected abstract void appendTo(StringBuilder sb); - - protected static void appendValue(StringBuilder sb, Object value) { - if (value instanceof JSONStringBuilder) { - ((JSONStringBuilder) value).appendTo(sb); - } else if (value instanceof Integer || value instanceof Boolean || value == null) { - sb.append(value); - } else { - sb.append(quote(String.valueOf(value))); - } - } - } - - public static final class JSONObjectBuilder extends JSONStringBuilder { - private final Map contents = new LinkedHashMap<>(); - - private JSONObjectBuilder() { - } - - public JSONObjectBuilder add(String key, String value) { - contents.put(key, value); - return this; - } - - public JSONObjectBuilder add(String key, Number value) { - contents.put(key, value); - return this; - } - - public JSONObjectBuilder add(String key, Boolean value) { - contents.put(key, value); - return this; - } - - public JSONObjectBuilder add(String key, JSONStringBuilder value) { - contents.put(key, value); - return this; - } - - @Override - protected void appendTo(StringBuilder sb) { - sb.append("{"); - boolean comma = false; - for (Map.Entry entry : contents.entrySet()) { - if (comma) { - sb.append(", "); - } - sb.append(quote(entry.getKey())); - sb.append(": "); - appendValue(sb, entry.getValue()); - comma = true; - } - sb.append("}"); - } - } - - public static final class JSONArrayBuilder extends JSONStringBuilder { - private final List contents = new ArrayList<>(); - - private JSONArrayBuilder() { - } - - public JSONArrayBuilder add(String value) { - contents.add(value); - return this; - } - - public JSONArrayBuilder add(Number value) { - contents.add(value); - return this; - } - - public JSONArrayBuilder add(Boolean value) { - contents.add(value); - return this; - } - - public JSONArrayBuilder add(JSONStringBuilder value) { - contents.add(value); - return this; - } - - @Override - protected void appendTo(StringBuilder sb) { - sb.append("["); - boolean comma = false; - for (Object value : contents) { - if (comma) { - sb.append(", "); - } - appendValue(sb, value); - comma = true; - } - sb.append("]"); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/NeverValidAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/NeverValidAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.nodes.*; - -/** - * An assumption that is never valid. Used as a placeholder where an assumption is needed that - * should be invalid from the start. - */ -public final class NeverValidAssumption implements Assumption { - - public static final NeverValidAssumption INSTANCE = new NeverValidAssumption(); - - private NeverValidAssumption() { - } - - @Override - public void check() throws InvalidAssumptionException { - throw new InvalidAssumptionException(); - } - - @Override - public void invalidate() { - } - - @Override - public String getName() { - return getClass().getName(); - } - - @Override - public boolean isValid() { - return false; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * Represents a {@link ValueProfile} that speculates on the primitive equality or object identity of - * values. - *

- * Note that for {@code float} and {@code double} values we compare primitive equality via - * {@link Float#floatToRawIntBits} and {@link Double#doubleToRawLongBits}, so that for example - * {@code -0.0} is not considered the same as {@code 0.0}, even though primitive equality would - * normally say that it was. - */ -public class PrimitiveValueProfile extends ValueProfile { - - private static final Object UNINITIALIZED = new Object(); - private static final Object GENERIC = new Object(); - - @CompilationFinal private Object cachedValue = UNINITIALIZED; - - PrimitiveValueProfile() { - } - - @SuppressWarnings("unchecked") - @Override - public Object profile(Object value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Byte) { - if (value instanceof Byte && (byte) snapshot == (byte) value) { - return snapshot; - } - } else if (snapshot instanceof Short) { - if (value instanceof Short && (short) snapshot == (short) value) { - return snapshot; - } - } else if (snapshot instanceof Integer) { - if (value instanceof Integer && (int) snapshot == (int) value) { - return snapshot; - } - } else if (snapshot instanceof Long) { - if (value instanceof Long && (long) snapshot == (long) value) { - return snapshot; - } - } else if (snapshot instanceof Float) { - if (value instanceof Float && exactCompare((float) snapshot, (float) value)) { - return snapshot; - } - } else if (snapshot instanceof Double) { - if (value instanceof Double && exactCompare((double) snapshot, (double) value)) { - return snapshot; - } - } else if (snapshot instanceof Boolean) { - if (value instanceof Boolean && (boolean) snapshot == (boolean) value) { - return snapshot; - } - } else if (snapshot instanceof Character) { - if (value instanceof Character && (char) snapshot == (char) value) { - return snapshot; - } - } else if (snapshot == value) { - return snapshot; - } - cacheMiss(value); - } - return value; - } - - public byte profile(byte value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Byte && (byte) snapshot == value) { - return (byte) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public short profile(short value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Short && (short) snapshot == value) { - return (short) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public int profile(int value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Integer && (int) snapshot == value) { - return (int) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public long profile(long value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Long && (long) snapshot == value) { - return (long) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public float profile(float value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Float && exactCompare((float) snapshot, value)) { - return (float) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public double profile(double value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Double && exactCompare((double) snapshot, value)) { - return (double) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public boolean profile(boolean value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Boolean && (boolean) snapshot == value) { - return (boolean) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public char profile(char value) { - Object snapshot = this.cachedValue; - if (snapshot != GENERIC) { - if (snapshot instanceof Character && (char) snapshot == value) { - return (char) snapshot; - } else { - cacheMiss(value); - } - } - return value; - } - - public boolean isGeneric() { - return cachedValue == GENERIC; - } - - public boolean isUninitialized() { - return cachedValue == UNINITIALIZED; - } - - public Object getCachedValue() { - return cachedValue; - } - - @Override - public String toString() { - return String.format("%s(%s)@%x", getClass().getSimpleName(), formatValue(), hashCode()); - } - - private void cacheMiss(Object value) { - // TODO should we try to handle this more atomically? - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (cachedValue == UNINITIALIZED) { - cachedValue = value; - } else { - cachedValue = GENERIC; - } - } - - public static boolean exactCompare(float a, float b) { - /* - * -0.0 == 0.0, but you can tell the difference through other means, so we need to - * differentiate. - */ - return Float.floatToRawIntBits(a) == Float.floatToRawIntBits(b); - } - - public static boolean exactCompare(double a, double b) { - /* - * -0.0 == 0.0, but you can tell the difference through other means, so we need to - * differentiate. - */ - return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b); - } - - private String formatValue() { - Object snapshot = this.cachedValue; - if (snapshot == null) { - return "null"; - } else if (snapshot == UNINITIALIZED) { - return "uninitialized"; - } else if (snapshot == GENERIC) { - return "generic"; - } else if (snapshot instanceof Byte || snapshot instanceof Short || snapshot instanceof Integer || snapshot instanceof Long || snapshot instanceof Float || snapshot instanceof Double || - snapshot instanceof Boolean || snapshot instanceof Character) { - return String.format("%s=%s", snapshot.getClass().getSimpleName(), snapshot); - } else { - return String.format("%s@%x", snapshot.getClass().getSimpleName(), Objects.hash(snapshot)); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/UnionAssumption.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/UnionAssumption.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; -import com.oracle.truffle.api.nodes.*; - -/** - * An assumption that combines two other assumptions. A check on this assumption checks both of the - * child assumptions. - */ -public class UnionAssumption implements Assumption { - - private final String name; - private final Assumption first; - private final Assumption second; - - public UnionAssumption(String name, Assumption first, Assumption second) { - this.name = name; - this.first = first; - this.second = second; - } - - public UnionAssumption(Assumption first, Assumption second) { - this(null, first, second); - } - - @Override - public void check() throws InvalidAssumptionException { - first.check(); - second.check(); - } - - @Override - public void invalidate() { - first.invalidate(); - second.invalidate(); - } - - @Override - public String getName() { - return name; - } - - @Override - public boolean isValid() { - return first.isValid() && second.isValid(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.*; - -/** - * Utility class to speculate on certain properties of values. - * - * Example usage: - * - *

- * private final ValueProfile classProfile = ValueProfile.createClassProfile();
- *
- * return classProfile.profile(value);
- * 
- * - * All instances of {@code ValueProfile} (and subclasses) must be held in {@code final} fields for - * compiler optimizations to take effect. - * - * @see #createPrimitiveProfile() - * @see #createIdentityProfile() - * @see #createClassProfile() - */ -public abstract class ValueProfile extends NodeCloneable { - - public abstract T profile(T value); - - /** - * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or object - * identity of a value. - */ - public static PrimitiveValueProfile createPrimitiveProfile() { - return new PrimitiveValueProfile(); - } - - /** - * Returns a {@link ValueProfile} that speculates on the exact class of a value. - */ - public static ValueProfile createClassProfile() { - return new ExactClassValueProfile(); - } - - /** - * Returns a {@link ValueProfile} that speculates on the object identity of a value. - */ - public static ValueProfile createIdentityProfile() { - return new IdentityValueProfile(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,565 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.nio.file.*; -import java.util.*; -import java.util.logging.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.TruffleLanguage.Registration; -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -/** - * Virtual machine for Truffle based languages. Use {@link #newVM()} to create new isolated virtual - * machine ready for execution of various languages. All the languages in a single virtual machine - * see each other exported global symbols and can cooperate. Use {@link #newVM()} multiple times to - * create different, isolated virtual machines completely separated from each other. - *

- * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly - * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}. - * Support for individual languages is initialized on demand - e.g. once a file of certain MIME type - * is about to be processed, its appropriate engine (if found), is initialized. Once an engine gets - * initialized, it remains so, until the virtual machine isn't garbage collected. - *

- * The TruffleVM is single-threaded and tries to enforce that. It records the thread it - * has been {@link Builder#build() created} by and checks that all subsequent calls are coming from - * the same thread. - */ -public final class TruffleVM { - private static final Logger LOG = Logger.getLogger(TruffleVM.class.getName()); - private static final SPIAccessor SPI = new SPIAccessor(); - private final Thread initThread; - private final Map langs; - private final Reader in; - private final Writer err; - private final Writer out; - - /** - * Private & temporary only constructor. - */ - private TruffleVM() { - this.initThread = null; - this.in = null; - this.err = null; - this.out = null; - this.langs = null; - } - - /** - * Real constructor used from the builder. - * - * @param out stdout - * @param err stderr - * @param in stdin - */ - private TruffleVM(Writer out, Writer err, Reader in) { - this.out = out; - this.err = err; - this.in = in; - this.initThread = Thread.currentThread(); - this.langs = new HashMap<>(); - Enumeration en; - try { - en = loader().getResources("META-INF/truffle/language"); - } catch (IOException ex) { - throw new IllegalStateException("Cannot read list of Truffle languages", ex); - } - while (en.hasMoreElements()) { - URL u = en.nextElement(); - Properties p; - try { - p = new Properties(); - try (InputStream is = u.openStream()) { - p.load(is); - } - } catch (IOException ex) { - LOG.log(Level.CONFIG, "Cannot process " + u + " as language definition", ex); - continue; - } - for (int cnt = 1;; cnt++) { - String prefix = "language" + cnt + "."; - if (p.getProperty(prefix + "name") == null) { - break; - } - Language l = new Language(prefix, p); - for (String mimeType : l.getMimeTypes()) { - langs.put(mimeType, l); - } - } - } - } - - static ClassLoader loader() { - ClassLoader l = TruffleVM.class.getClassLoader(); - if (l == null) { - l = ClassLoader.getSystemClassLoader(); - } - return l; - } - - /** - * Creation of new Truffle virtual machine. Use the {@link Builder} methods to configure your - * virtual machine and then create one using {@link Builder#build()}: - * - *

-     * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()}
-     *     .{@link Builder#stdOut(java.io.Writer) stdOut}({@link Writer yourWriter})
-     *     .{@link Builder#stdErr(java.io.Writer) stdErr}({@link Writer yourWriter})
-     *     .{@link Builder#stdIn(java.io.Reader) stdIn}({@link Reader yourReader})
-     *     .{@link Builder#build() build()};
-     * 
- * - * It searches for {@link Registration languages registered} in the system class loader and - * makes them available for later evaluation via - * {@link #eval(java.lang.String, java.lang.String)} methods. - * - * @return new, isolated virtual machine with pre-registered languages - */ - public static TruffleVM.Builder newVM() { - // making Builder non-static inner class is a - // nasty trick to avoid the Builder class to appear - // in Javadoc next to TruffleVM class - TruffleVM vm = new TruffleVM(); - return vm.new Builder(); - } - - /** - * Builder for a new {@link TruffleVM}. Call various configuration methods in a chain and at the - * end create new {@link TruffleVM virtual machine}: - * - *
-     * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()}
-     *     .{@link Builder#stdOut(java.io.Writer) stdOut}({@link Writer yourWriter})
-     *     .{@link Builder#stdErr(java.io.Writer) stdErr}({@link Writer yourWriter})
-     *     .{@link Builder#stdIn(java.io.Reader) stdIn}({@link Reader yourReader})
-     *     .{@link Builder#build() build()};
-     * 
- */ - public final class Builder { - private Writer out; - private Writer err; - private Reader in; - - Builder() { - } - - /** - * Changes the defaut output for languages running in to be created - * {@link TruffleVM virtual machine}. The default is to use {@link System#out}. - * - * @param w the writer to use as output - * @return instance of this builder - */ - public Builder stdOut(Writer w) { - out = w; - return this; - } - - /** - * Changes the error output for languages running in to be created - * {@link TruffleVM virtual machine}. The default is to use {@link System#err}. - * - * @param w the writer to use as output - * @return instance of this builder - */ - public Builder stdErr(Writer w) { - err = w; - return this; - } - - /** - * Changes the default input for languages running in to be created - * {@link TruffleVM virtual machine}. The default is to use {@link System#out}. - * - * @param r the reader to use as input - * @return instance of this builder - */ - public Builder stdIn(Reader r) { - in = r; - return this; - } - - /** - * Creates the {@link TruffleVM Truffle virtual machine}. The configuration is taken from - * values passed into configuration methods in this class. - * - * @return new, isolated virtual machine with pre-registered languages - */ - public TruffleVM build() { - if (out == null) { - out = new OutputStreamWriter(System.out); - } - if (err == null) { - err = new OutputStreamWriter(System.err); - } - if (in == null) { - in = new InputStreamReader(System.in); - } - return new TruffleVM(out, err, in); - } - } - - /** - * Descriptions of languages supported in this Truffle virtual machine. - * - * @return an immutable map with keys being MIME types and values the {@link Language - * descriptions} of associated languages - */ - public Map getLanguages() { - return Collections.unmodifiableMap(langs); - } - - /** - * Evaluates file located on a given URL. Is equivalent to loading the content of a file and - * executing it via {@link #eval(java.lang.String, java.lang.String)} with a MIME type guess - * based on the file's extension and/or content. - * - * @param location the location of a file to execute - * @return result of a processing the file, possibly null - * @throws IOException exception to signal I/O problems or problems with processing the file's - * content - */ - public Object eval(URI location) throws IOException { - checkThread(); - Source s; - String mimeType; - if (location.getScheme().equals("file")) { - File file = new File(location); - s = Source.fromFileName(file.getPath(), true); - if (file.getName().endsWith(".c")) { - mimeType = "text/x-c"; - } else if (file.getName().endsWith(".sl")) { - mimeType = "application/x-sl"; - } else { - mimeType = Files.probeContentType(file.toPath()); - } - } else { - URL url = location.toURL(); - s = Source.fromURL(url, location.toString()); - URLConnection conn = url.openConnection(); - mimeType = conn.getContentType(); - } - TruffleLanguage l = getTruffleLang(mimeType); - if (l == null) { - throw new IOException("No language for " + location + " with MIME type " + mimeType + " found. Supported types: " + langs.keySet()); - } - return SPI.eval(l, s); - } - - /** - * Evaluates code snippet. Chooses a language registered for a given MIME type (throws - * {@link IOException} if there is none). And passes the specified code to it for execution. - * - * @param mimeType MIME type of the code snippet - chooses the right language - * @param reader the source of code snippet to execute - * @return result of an execution, possibly null - * @throws IOException thrown to signal errors while processing the code - */ - public Object eval(String mimeType, Reader reader) throws IOException { - checkThread(); - TruffleLanguage l = getTruffleLang(mimeType); - if (l == null) { - throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet()); - } - return SPI.eval(l, Source.fromReader(reader, mimeType)); - } - - /** - * Evaluates code snippet. Chooses a language registered for a given MIME type (throws - * {@link IOException} if there is none). And passes the specified code to it for execution. - * - * @param mimeType MIME type of the code snippet - chooses the right language - * @param code the code snippet to execute - * @return result of an execution, possibly null - * @throws IOException thrown to signal errors while processing the code - */ - public Object eval(String mimeType, String code) throws IOException { - checkThread(); - TruffleLanguage l = getTruffleLang(mimeType); - if (l == null) { - throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet()); - } - return SPI.eval(l, Source.fromText(code, mimeType)); - } - - /** - * Looks global symbol provided by one of initialized languages up. First of all execute your - * program via one of your {@link #eval(java.lang.String, java.lang.String)} and then look - * expected symbol up using this method. - *

- * The names of the symbols are language dependent, but for example the Java language bindings - * follow the specification for method references: - *

    - *
  • "java.lang.Exception::new" is a reference to constructor of {@link Exception} - *
  • "java.lang.Integer::valueOf" is a reference to static method in {@link Integer} class - *
- * Once an symbol is obtained, it remembers values for fast access and is ready for being - * invoked. - * - * @param globalName the name of the symbol to find - * @return found symbol or null if it has not been found - */ - public Symbol findGlobalSymbol(String globalName) { - checkThread(); - Object obj = null; - Object global = null; - for (Language dl : langs.values()) { - TruffleLanguage l = dl.getImpl(); - obj = SPI.findExportedSymbol(l, globalName, true); - if (obj != null) { - global = SPI.languageGlobal(l); - break; - } - } - if (obj == null) { - for (Language dl : langs.values()) { - TruffleLanguage l = dl.getImpl(); - obj = SPI.findExportedSymbol(l, globalName, false); - if (obj != null) { - global = SPI.languageGlobal(l); - break; - } - } - } - return obj == null ? null : new Symbol(obj, global); - } - - private void checkThread() { - if (initThread != Thread.currentThread()) { - throw new IllegalStateException("TruffleVM created on " + initThread.getName() + " but used on " + Thread.currentThread().getName()); - } - } - - private TruffleLanguage getTruffleLang(String mimeType) { - checkThread(); - Language l = langs.get(mimeType); - return l == null ? null : l.getImpl(); - } - - /** - * Represents {@link TruffleVM#findGlobalSymbol(java.lang.String) global symbol} provided by one - * of the initialized languages in {@link TruffleVM Truffle virtual machine}. - */ - public class Symbol { - private final Object obj; - private final Object global; - - Symbol(Object obj, Object global) { - this.obj = obj; - this.global = global; - } - - /** - * Invokes the symbol. If the symbol represents a function, then it should be invoked with - * provided arguments. If the symbol represents a field, then first argument (if provided) - * should set the value to the field; the return value should be the actual value of the - * field when the invoke method returns. - * - * @param thiz this/self in language that support such concept; use null to let - * the language use default this/self or ignore the value - * @param args arguments to pass when invoking the symbol - * @return the value returned by invoking the symbol - * @throws IOException signals problem during execution - */ - public Object invoke(Object thiz, Object... args) throws IOException { - List arr = new ArrayList<>(); - if (thiz == null) { - if (global != null) { - arr.add(global); - } - } else { - arr.add(thiz); - } - arr.addAll(Arrays.asList(args)); - return SPI.invoke(obj, arr.toArray()); - } - } - - /** - * Description of a language registered in {@link TruffleVM Truffle virtual machine}. Languages - * are registered by {@link Registration} annotation which stores necessary information into a - * descriptor inside of the language's JAR file. When a new {@link TruffleVM} is created, it - * reads all available descriptors and creates {@link Language} objects to represent them. One - * can obtain a {@link #getName() name} or list of supported {@link #getMimeTypes() MIME types} - * for each language. The actual language implementation is not initialized until - * {@link TruffleVM#eval(java.lang.String, java.lang.String) a code is evaluated} in it. - */ - public final class Language { - private final Properties props; - private TruffleLanguage impl; - private final String prefix; - private String shortName; - - Language(String prefix, Properties props) { - this.prefix = prefix; - this.props = props; - } - - /** - * MIME types recognized by the language. - * - * @return returns immutable set of recognized MIME types - */ - public Set getMimeTypes() { - TreeSet ts = new TreeSet<>(); - for (int i = 0;; i++) { - String mt = props.getProperty(prefix + "mimeType." + i); - if (mt == null) { - break; - } - ts.add(mt); - } - return Collections.unmodifiableSet(ts); - } - - /** - * Human readable name of the language. Think of C, Ruby, JS, etc. - * - * @return string giving the language a name - */ - public String getName() { - return props.getProperty(prefix + "name"); - } - - /** - * Name of the language version. - * - * @return string specifying the language version - */ - public String getVersion() { - return props.getProperty(prefix + "version"); - } - - /** - * Human readable string that identifies the language and version. - * - * @return string describing the specific language version - */ - public String getShortName() { - if (shortName == null) { - shortName = getName() + "(" + getVersion() + ")"; - } - return shortName; - } - - public ToolSupportProvider getToolSupport() { - return SPI.getToolSupport(getImpl()); - } - - public DebugSupportProvider getDebugSupport() { - return SPI.getDebugSupport(getImpl()); - } - - TruffleLanguage getImpl() { - if (impl == null) { - String n = props.getProperty(prefix + "className"); - try { - Class langClazz = Class.forName(n, true, loader()); - Constructor constructor = langClazz.getConstructor(Env.class); - impl = SPI.attachEnv(TruffleVM.this, constructor, out, err, in); - } catch (Exception ex) { - throw new IllegalStateException("Cannot initialize " + getShortName() + " language with implementation " + n, ex); - } - } - return impl; - } - - @Override - public String toString() { - return "[" + getShortName() + " for " + getMimeTypes() + "]"; - } - } // end of Language - - private static class SPIAccessor extends Accessor { - @Override - public Object importSymbol(TruffleVM vm, TruffleLanguage ownLang, String globalName) { - Set uniqueLang = new LinkedHashSet<>(vm.langs.values()); - for (Language dl : uniqueLang) { - TruffleLanguage l = dl.getImpl(); - if (l == ownLang) { - continue; - } - Object obj = SPI.findExportedSymbol(l, globalName, true); - if (obj != null) { - return obj; - } - } - for (Language dl : uniqueLang) { - TruffleLanguage l = dl.getImpl(); - if (l == ownLang) { - continue; - } - Object obj = SPI.findExportedSymbol(l, globalName, false); - if (obj != null) { - return obj; - } - } - return null; - } - - @Override - public TruffleLanguage attachEnv(TruffleVM vm, Constructor langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { - return super.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); - } - - @Override - public Object eval(TruffleLanguage l, Source s) throws IOException { - return super.eval(l, s); - } - - @Override - public Object findExportedSymbol(TruffleLanguage l, String globalName, boolean onlyExplicit) { - return super.findExportedSymbol(l, globalName, onlyExplicit); - } - - @Override - public Object languageGlobal(TruffleLanguage l) { - return super.languageGlobal(l); - } - - @Override - public Object invoke(Object obj, Object[] args) throws IOException { - return super.invoke(obj, args); - } - - @Override - public ToolSupportProvider getToolSupport(TruffleLanguage l) { - return super.getToolSupport(l); - } - - @Override - public DebugSupportProvider getDebugSupport(TruffleLanguage l) { - return super.getDebugSupport(l); - } - } // end of SPIAccessor -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/package.html --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/package.html Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ - - - - Truffle Virtual Machine - - - - -
Central place to control Truffle Virtual Machine and - all languages hosted in it.
- - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/.checkstyle_checks.xml --- a/graal/com.oracle.truffle.dsl.processor/.checkstyle_checks.xml Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor --- a/graal/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -com.oracle.truffle.dsl.processor.TruffleProcessor -com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor -com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +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.dsl.processor; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.generator.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.java.transform.*; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.parser.*; - -/** - * THIS IS NOT PUBLIC API. - */ -class AnnotationProcessor { - - private final AbstractParser parser; - private final CodeTypeElementFactory factory; - - private final Set processedElements = new HashSet<>(); - - public AnnotationProcessor(AbstractParser parser, CodeTypeElementFactory factory) { - this.parser = parser; - this.factory = factory; - } - - public AbstractParser getParser() { - return parser; - } - - @SuppressWarnings({"unchecked"}) - public void process(Element element, boolean callback) { - // since it is not guaranteed to be called only once by the compiler - // we check for already processed elements to avoid errors when writing files. - if (!callback && element instanceof TypeElement) { - String qualifiedName = ElementUtils.getQualifiedName((TypeElement) element); - if (processedElements.contains(qualifiedName)) { - return; - } - processedElements.add(qualifiedName); - } - - ProcessorContext context = ProcessorContext.getInstance(); - TypeElement type = (TypeElement) element; - - M model = (M) context.getTemplate(type.asType(), false); - boolean firstRun = !context.containsTemplate(type); - - if (firstRun || !callback) { - context.registerTemplate(type, null); - model = parser.parse(element); - context.registerTemplate(type, model); - - if (model != null) { - CodeTypeElement unit; - try { - unit = factory.create(ProcessorContext.getInstance(), model); - } catch (Throwable e) { - throw new RuntimeException(String.format("Failed to write code for %s. Parserdump:%s.", ElementUtils.getQualifiedName(type), ""), e); - } - if (unit == null) { - return; - } - unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation()); - unit.setGeneratorElement(model.getTemplateType()); - - DeclaredType overrideType = (DeclaredType) context.getType(Override.class); - DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class); - unit.accept(new GenerateOverrideVisitor(overrideType), null); - unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null); - - if (!callback) { - unit.accept(new CodeWriter(context.getEnvironment(), element), null); - } - } - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CodeWriter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CodeWriter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.dsl.processor; - -import java.io.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.tools.*; - -import com.oracle.truffle.dsl.processor.java.compiler.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.java.transform.*; - -public final class CodeWriter extends AbstractCodeWriter { - - private final Element originalElement; - private final ProcessingEnvironment env; - - public CodeWriter(ProcessingEnvironment env, Element originalElement) { - this.env = env; - this.originalElement = originalElement; - } - - @Override - protected Writer createWriter(CodeTypeElement clazz) throws IOException { - JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), originalElement); - return new BufferedWriter(jfo.openWriter()); - } - - @Override - protected void writeHeader() { - if (env == null) { - return; - } - String comment = CompilerFactory.getCompiler(originalElement).getHeaderComment(env, originalElement); - if (comment != null) { - writeLn(comment); - } - writeLn("// CheckStyle: start generated"); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CompileErrorException.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CompileErrorException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +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.dsl.processor; - -public class CompileErrorException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public CompileErrorException(String message) { - super(message); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ExpectError.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ExpectError.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +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.dsl.processor; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.tools.Diagnostic.*; - -public class ExpectError { - - public static void assertNoErrorExpected(ProcessingEnvironment processingEnv, Element element) { - TypeElement eee = processingEnv.getElementUtils().getTypeElement(TruffleTypes.EXPECT_ERROR_CLASS_NAME); - if (eee != null) { - for (AnnotationMirror am : element.getAnnotationMirrors()) { - if (am.getAnnotationType().asElement().equals(eee)) { - processingEnv.getMessager().printMessage(Kind.ERROR, "Expected an error, but none found!", element); - } - } - } - } - - public static boolean isExpectedError(ProcessingEnvironment processingEnv, Element element, String message) { - TypeElement eee = processingEnv.getElementUtils().getTypeElement(TruffleTypes.EXPECT_ERROR_CLASS_NAME); - if (eee != null) { - for (AnnotationMirror am : element.getAnnotationMirrors()) { - if (am.getAnnotationType().asElement().equals(eee)) { - Map vals = am.getElementValues(); - if (vals.size() == 1) { - AnnotationValue av = vals.values().iterator().next(); - if (av.getValue() instanceof List) { - List arr = (List) av.getValue(); - for (Object o : arr) { - if (o instanceof AnnotationValue) { - AnnotationValue ov = (AnnotationValue) o; - if (message.equals(ov.getValue())) { - return true; - } - } - } - } - } - } - } - } - return false; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/LanguageRegistrationProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/LanguageRegistrationProcessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +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.dsl.processor; - -import java.io.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.*; -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.tools.Diagnostic.Kind; -import javax.tools.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.TruffleLanguage.Registration; - -@SupportedAnnotationTypes("com.oracle.truffle.api.*") -public final class LanguageRegistrationProcessor extends AbstractProcessor { - private final List registrations = new ArrayList<>(); - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - private void generateFile(List languages) { - String filename = "META-INF/truffle/language"; - Properties p = new Properties(); - int cnt = 0; - for (TypeElement l : languages) { - Registration annotation = l.getAnnotation(Registration.class); - if (annotation == null) { - continue; - } - String prefix = "language" + ++cnt + "."; - String className = processingEnv.getElementUtils().getBinaryName(l).toString(); - p.setProperty(prefix + "name", annotation.name()); - p.setProperty(prefix + "version", annotation.version()); - p.setProperty(prefix + "className", className); - String[] mimes = annotation.mimeType(); - for (int i = 0; i < mimes.length; i++) { - p.setProperty(prefix + "mimeType." + i, mimes[i]); - } - } - if (cnt > 0) { - try { - FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, languages.toArray(new Element[0])); - try (OutputStream os = file.openOutputStream()) { - p.store(os, "Generated by " + LanguageRegistrationProcessor.class.getName()); - } - } catch (IOException e) { - processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), languages.get(0)); - } - } - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - if (roundEnv.processingOver()) { - generateFile(registrations); - registrations.clear(); - return true; - } - for (Element e : roundEnv.getElementsAnnotatedWith(Registration.class)) { - Registration annotation = e.getAnnotation(Registration.class); - if (annotation != null && e.getKind() == ElementKind.CLASS) { - if (!e.getModifiers().contains(Modifier.PUBLIC)) { - emitError("Registered language class must be public", e); - continue; - } - if (e.getEnclosingElement().getKind() != ElementKind.PACKAGE && !e.getModifiers().contains(Modifier.STATIC)) { - emitError("Registered language inner-class must be static", e); - continue; - } - TypeMirror truffleLang = processingEnv.getElementUtils().getTypeElement(TruffleLanguage.class.getName()).asType(); - if (!processingEnv.getTypeUtils().isAssignable(e.asType(), truffleLang)) { - emitError("Registered language class must subclass TruffleLanguage", e); - continue; - } - boolean found = false; - for (Element mem : e.getEnclosedElements()) { - if (mem.getKind() != ElementKind.CONSTRUCTOR) { - continue; - } - ExecutableElement ee = (ExecutableElement) mem; - if (ee.getParameters().size() != 1) { - continue; - } - if (!ee.getModifiers().contains(Modifier.PUBLIC)) { - continue; - } - TypeMirror env = processingEnv.getElementUtils().getTypeElement(TruffleLanguage.Env.class.getCanonicalName()).asType(); - if (processingEnv.getTypeUtils().isSameType(ee.getParameters().get(0).asType(), env)) { - found = true; - break; - } - } - if (!found) { - emitError("Language must have a public constructor accepting TruffleLanguage.Env as parameter", e); - continue; - } - assertNoErrorExpected(e); - registrations.add((TypeElement) e); - } - } - - return true; - } - - void assertNoErrorExpected(Element e) { - ExpectError.assertNoErrorExpected(processingEnv, e); - } - - void emitError(String msg, Element e) { - if (ExpectError.isExpectedError(processingEnv, e, msg)) { - return; - } - processingEnv.getMessager().printMessage(Kind.ERROR, msg, e); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Log.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Log.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.dsl.processor; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.dsl.processor.java.model.*; - -/** - * THIS IS NOT PUBLIC API. - */ -public class Log { - - public static boolean isDebug() { - return false; - } - - private final ProcessingEnvironment processingEnv; - - public Log(ProcessingEnvironment env) { - this.processingEnv = env; - } - - public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) { - AnnotationMirror usedMirror = mirror; - Element usedElement = element; - AnnotationValue usedValue = value; - String message = String.format(format, args); - - if (element instanceof GeneratedElement) { - usedMirror = ((GeneratedElement) element).getGeneratorAnnotationMirror(); - usedElement = ((GeneratedElement) element).getGeneratorElement(); - usedValue = null; - if (usedElement != null) { - message = String.format("Element %s: %s", element, message); - } - } - processingEnv.getMessager().printMessage(kind, message, usedElement, usedMirror, usedValue); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ProcessorContext.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ProcessorContext.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +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.dsl.processor; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -/** - * THIS IS NOT PUBLIC API. - */ -public class ProcessorContext { - - private final ProcessingEnvironment environment; - - private final Map models = new HashMap<>(); - - private final ProcessCallback callback; - private final Log log; - private final TruffleTypes truffleTypes; - - ProcessorContext(ProcessingEnvironment env, ProcessCallback callback) { - this.environment = env; - this.callback = callback; - this.log = new Log(environment); - this.truffleTypes = new TruffleTypes(this); - } - - public TruffleTypes getTruffleTypes() { - return truffleTypes; - } - - public Log getLog() { - return log; - } - - public ProcessingEnvironment getEnvironment() { - return environment; - } - - public boolean containsTemplate(TypeElement element) { - return models.containsKey(ElementUtils.getQualifiedName(element)); - } - - public void registerTemplate(TypeElement element, Template model) { - models.put(ElementUtils.getQualifiedName(element), model); - } - - public Template getTemplate(TypeMirror templateTypeMirror, boolean invokeCallback) { - String qualifiedName = ElementUtils.getQualifiedName(templateTypeMirror); - Template model = models.get(qualifiedName); - if (model == null && invokeCallback) { - callback.callback(ElementUtils.fromTypeMirror(templateTypeMirror)); - model = models.get(qualifiedName); - } - return model; - } - - public DeclaredType getDeclaredType(Class element) { - return (DeclaredType) ElementUtils.getType(environment, element); - } - - public boolean isType(TypeMirror type, Class clazz) { - return ElementUtils.typeEquals(type, getType(clazz)); - } - - public TypeMirror getType(Class element) { - return ElementUtils.getType(environment, element); - } - - public interface ProcessCallback { - - void callback(TypeElement template); - - } - - public TypeMirror reloadTypeElement(TypeElement type) { - return getType(type.getQualifiedName().toString()); - } - - private TypeMirror getType(String className) { - TypeElement element = environment.getElementUtils().getTypeElement(className); - if (element != null) { - return element.asType(); - } - return null; - } - - public TypeMirror reloadType(TypeMirror type) { - if (type instanceof CodeTypeMirror) { - return type; - } else if (type.getKind().isPrimitive()) { - return type; - } - Types types = getEnvironment().getTypeUtils(); - - switch (type.getKind()) { - case ARRAY: - return types.getArrayType(reloadType(((ArrayType) type).getComponentType())); - case WILDCARD: - return types.getWildcardType(((WildcardType) type).getExtendsBound(), ((WildcardType) type).getSuperBound()); - case DECLARED: - return reloadTypeElement((TypeElement) (((DeclaredType) type).asElement())); - } - return type; - } - - private static final ThreadLocal instance = new ThreadLocal<>(); - - public static void setThreadLocalInstance(ProcessorContext context) { - instance.set(context); - } - - public static ProcessorContext getInstance() { - return instance.get(); - } - - public List getFrameTypes() { - return Arrays.asList(getType(VirtualFrame.class), getType(MaterializedFrame.class), getType(Frame.class)); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +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.dsl.processor; - -import java.lang.annotation.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.*; -import javax.lang.model.element.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.dsl.processor.ProcessorContext.ProcessCallback; -import com.oracle.truffle.dsl.processor.generator.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.parser.*; - -/** - * THIS IS NOT PUBLIC API. - */ -// @SupportedAnnotationTypes({"com.oracle.truffle.codegen.Operation", -// "com.oracle.truffle.codegen.TypeLattice"}) -public class TruffleProcessor extends AbstractProcessor implements ProcessCallback { - - private List> generators; - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - if (!roundEnv.processingOver()) { - processImpl(roundEnv); - } - return false; - } - - private void processImpl(RoundEnvironment env) { - // TODO run verifications that other annotations are not processed out of scope of the - // operation or typelattice. - try { - ProcessorContext.setThreadLocalInstance(new ProcessorContext(processingEnv, this)); - for (AnnotationProcessor generator : getGenerators()) { - AbstractParser parser = generator.getParser(); - if (parser.getAnnotationType() != null) { - for (Element e : env.getElementsAnnotatedWith(parser.getAnnotationType())) { - processElement(generator, e, false); - } - } - - for (Class annotationType : parser.getTypeDelegatedAnnotationTypes()) { - for (Element e : env.getElementsAnnotatedWith(annotationType)) { - TypeElement processedType; - if (parser.isDelegateToRootDeclaredType()) { - processedType = ElementUtils.findRootEnclosingType(e); - } else { - processedType = ElementUtils.findNearestEnclosingType(e); - } - processElement(generator, processedType, false); - } - } - - } - } finally { - ProcessorContext.setThreadLocalInstance(null); - } - } - - private static void processElement(AnnotationProcessor generator, Element e, boolean callback) { - try { - generator.process(e, callback); - } catch (Throwable e1) { - handleThrowable(generator, e1, e); - } - } - - private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) { - String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e + " "; - ProcessorContext.getInstance().getEnvironment().getMessager().printMessage(Kind.ERROR, message + ": " + ElementUtils.printException(t), e); - } - - @Override - public void callback(TypeElement template) { - for (AnnotationProcessor generator : generators) { - Class annotationType = generator.getParser().getAnnotationType(); - if (annotationType != null) { - Annotation annotation = template.getAnnotation(annotationType); - if (annotation != null) { - processElement(generator, template, true); - } - } - } - } - - @Override - public Set getSupportedAnnotationTypes() { - Set annotations = new HashSet<>(); - List> annotationsTypes = new ArrayList<>(); - annotationsTypes.addAll(NodeParser.ANNOTATIONS); - annotationsTypes.addAll(TypeSystemParser.ANNOTATIONS); - for (Class type : annotationsTypes) { - annotations.add(type.getCanonicalName()); - } - return annotations; - } - - private List> getGenerators() { - if (generators == null && processingEnv != null) { - generators = new ArrayList<>(); - generators.add(new AnnotationProcessor<>(new TypeSystemParser(), new TypeSystemCodeGenerator())); - generators.add(new AnnotationProcessor<>(new NodeParser(), new NodeCodeGenerator())); - } - return generators; - } - - @Override - public synchronized void init(ProcessingEnvironment env) { - this.processingEnv = env; - super.init(env); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +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.dsl.processor; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.source.*; - -/** - * THIS IS NOT PUBLIC API. - */ -public final class TruffleTypes { - - public static final String EXPECT_ERROR_CLASS_NAME = "com.oracle.truffle.api.dsl.test.ExpectError"; - - private final DeclaredType node; - private final ArrayType nodeArray; - private final TypeMirror unexpectedValueException; - private final TypeMirror frame; - private final TypeMirror assumption; - private final TypeMirror invalidAssumption; - private final DeclaredType childAnnotation; - private final DeclaredType childrenAnnotation; - private final DeclaredType nodeInfoAnnotation; - private final DeclaredType nodeCost; - private final TypeMirror compilerDirectives; - private final TypeMirror compilerAsserts; - private final DeclaredType truffleBoundary; - private final DeclaredType sourceSection; - private final DeclaredType truffleOptions; - private final DeclaredType compilationFinal; - private final DeclaredType nodeUtil; - private final DeclaredType dslNode; - private final DeclaredType dslShare; - private final DeclaredType nodeFactory; - private final DeclaredType nodeFactoryBase; - private final DeclaredType dslMetadata; - private final DeclaredType generateNodeFactory; - private final TypeElement expectError; - - private final List errors = new ArrayList<>(); - - TruffleTypes(ProcessorContext context) { - node = getRequired(context, Node.class); - nodeArray = context.getEnvironment().getTypeUtils().getArrayType(node); - unexpectedValueException = getRequired(context, UnexpectedResultException.class); - frame = getRequired(context, VirtualFrame.class); - childAnnotation = getRequired(context, Child.class); - childrenAnnotation = getRequired(context, Children.class); - compilerDirectives = getRequired(context, CompilerDirectives.class); - compilerAsserts = getRequired(context, CompilerAsserts.class); - assumption = getRequired(context, Assumption.class); - invalidAssumption = getRequired(context, InvalidAssumptionException.class); - nodeInfoAnnotation = getRequired(context, NodeInfo.class); - nodeCost = getRequired(context, NodeCost.class); - truffleBoundary = getRequired(context, TruffleBoundary.class); - sourceSection = getRequired(context, SourceSection.class); - truffleOptions = getRequired(context, TruffleOptions.class); - compilationFinal = getRequired(context, CompilationFinal.class); - nodeUtil = getRequired(context, NodeUtil.class); - dslNode = getRequired(context, DSLNode.class); - dslShare = getRequired(context, DSLShare.class); - nodeFactory = getRequired(context, NodeFactory.class); - nodeFactoryBase = getRequired(context, NodeFactoryBase.class); - dslMetadata = getRequired(context, DSLMetadata.class); - expectError = getOptional(context, EXPECT_ERROR_CLASS_NAME); - generateNodeFactory = getRequired(context, GenerateNodeFactory.class); - } - - public DeclaredType getGenerateNodeFactory() { - return generateNodeFactory; - } - - public DeclaredType getDslMetadata() { - return dslMetadata; - } - - public DeclaredType getNodeFactory() { - return nodeFactory; - } - - public DeclaredType getNodeFactoryBase() { - return nodeFactoryBase; - } - - public DeclaredType getDslNode() { - return dslNode; - } - - public DeclaredType getDslShare() { - return dslShare; - } - - public DeclaredType getCompilationFinal() { - return compilationFinal; - } - - public TypeElement getExpectError() { - return expectError; - } - - public DeclaredType getNodeInfoAnnotation() { - return nodeInfoAnnotation; - } - - public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) { - if (errors.isEmpty()) { - return true; - } - - for (String error : errors) { - context.getLog().message(Kind.ERROR, element, mirror, null, error); - } - - return false; - } - - public DeclaredType getNodeCost() { - return nodeCost; - } - - private DeclaredType getRequired(ProcessorContext context, Class clazz) { - TypeMirror type = context.getType(clazz); - if (type == null) { - errors.add(String.format("Could not find required type: %s", clazz.getSimpleName())); - } - return (DeclaredType) type; - } - - private static TypeElement getOptional(ProcessorContext context, String name) { - return context.getEnvironment().getElementUtils().getTypeElement(name); - } - - public TypeMirror getInvalidAssumption() { - return invalidAssumption; - } - - public TypeMirror getAssumption() { - return assumption; - } - - public TypeMirror getCompilerDirectives() { - return compilerDirectives; - } - - public DeclaredType getNode() { - return node; - } - - public ArrayType getNodeArray() { - return nodeArray; - } - - public TypeMirror getFrame() { - return frame; - } - - public TypeMirror getUnexpectedValueException() { - return unexpectedValueException; - } - - public DeclaredType getChildAnnotation() { - return childAnnotation; - } - - public DeclaredType getChildrenAnnotation() { - return childrenAnnotation; - } - - public TypeMirror getCompilerAsserts() { - return compilerAsserts; - } - - public DeclaredType getTruffleOptions() { - return truffleOptions; - } - - public DeclaredType getTruffleBoundary() { - return truffleBoundary; - } - - public DeclaredType getSourceSection() { - return sourceSection; - } - - public DeclaredType getNodeUtil() { - return nodeUtil; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Copyright.frame --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Copyright.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpression.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpression.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +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.dsl.processor.expression; - -import java.util.*; -import java.util.concurrent.atomic.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public abstract class DSLExpression { - - private TypeMirror resolvedTargetType; - - private DSLExpression() { - } - - public static DSLExpression parse(String input) { - return Parser.parse(input); - } - - public final Set findBoundVariableElements() { - final Set variables = new HashSet<>(); - this.accept(new AbstractDSLExpressionVisitor() { - - @Override - public void visitVariable(Variable variable) { - if (variable.getReceiver() == null) { - variables.add(variable.getResolvedVariable()); - } - } - - }); - return variables; - } - - public final Set findBoundVariables() { - final Set variables = new HashSet<>(); - this.accept(new AbstractDSLExpressionVisitor() { - - @Override - public void visitVariable(Variable variable) { - if (variable.getReceiver() == null) { - variables.add(variable); - } - } - - }); - return variables; - } - - public boolean containsComparisons() { - final AtomicBoolean found = new AtomicBoolean(); - this.accept(new AbstractDSLExpressionVisitor() { - @Override - public void visitBinary(Binary binary) { - if (binary.isComparison()) { - found.set(true); - } - } - }); - return found.get(); - } - - public void setResolvedTargetType(TypeMirror resolvedTargetType) { - this.resolvedTargetType = resolvedTargetType; - } - - public TypeMirror getResolvedTargetType() { - return resolvedTargetType; - } - - public abstract TypeMirror getResolvedType(); - - public abstract void accept(DSLExpressionVisitor visitor); - - public static final class Negate extends DSLExpression { - - private final DSLExpression receiver; - - public Negate(DSLExpression receiver) { - this.receiver = receiver; - } - - @Override - public void accept(DSLExpressionVisitor visitor) { - receiver.accept(visitor); - visitor.visitNegate(this); - } - - public DSLExpression getReceiver() { - return receiver; - } - - @Override - public TypeMirror getResolvedType() { - return receiver.getResolvedType(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Negate) { - return receiver.equals(((Negate) obj).receiver); - } - return false; - } - - @Override - public int hashCode() { - return receiver.hashCode(); - } - } - - public static final class Binary extends DSLExpression { - - private final String operator; - private final DSLExpression left; - private final DSLExpression right; - - private TypeMirror resolvedType; - - public Binary(String operator, DSLExpression left, DSLExpression right) { - this.operator = operator; - this.left = left; - this.right = right; - } - - public boolean isComparison() { - return DSLExpressionResolver.COMPARABLE_OPERATORS.contains(operator) || DSLExpressionResolver.IDENTITY_OPERATORS.contains(operator); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Binary) { - Binary other = (Binary) obj; - return operator.equals(other.operator) && left.equals(other.left) && right.equals(other.right); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(operator, left, right); - } - - public String getOperator() { - return operator; - } - - public DSLExpression getLeft() { - return left; - } - - public DSLExpression getRight() { - return right; - } - - @Override - public void accept(DSLExpressionVisitor visitor) { - left.accept(visitor); - right.accept(visitor); - visitor.visitBinary(this); - } - - @Override - public TypeMirror getResolvedType() { - return resolvedType; - } - - public void setResolvedType(TypeMirror resolvedType) { - this.resolvedType = resolvedType; - } - - @Override - public String toString() { - return "Binary [left=" + left + ", operator=" + operator + ", right=" + right + ", resolvedType=" + resolvedType + "]"; - } - - } - - public static final class Call extends DSLExpression { - - private final DSLExpression receiver; - private final String name; - private final List parameters; - - private ExecutableElement resolvedMethod; - - public Call(DSLExpression receiver, String name, List parameters) { - this.receiver = receiver; - this.name = name; - this.parameters = parameters; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Call) { - Call other = (Call) obj; - return Objects.equals(receiver, other.receiver) && name.equals(other.name) && parameters.equals(other.parameters); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(receiver, name, parameters); - } - - public DSLExpression getReceiver() { - return receiver; - } - - public String getName() { - return name; - } - - public List getParameters() { - return parameters; - } - - @Override - public void accept(DSLExpressionVisitor visitor) { - if (receiver != null) { - receiver.accept(visitor); - } - for (DSLExpression parameter : getParameters()) { - parameter.accept(visitor); - } - visitor.visitCall(this); - } - - @Override - public TypeMirror getResolvedType() { - if (resolvedMethod == null) { - return null; - } - if (resolvedMethod.getKind() == ElementKind.CONSTRUCTOR) { - return resolvedMethod.getEnclosingElement().asType(); - } else { - return resolvedMethod.getReturnType(); - } - } - - public ExecutableElement getResolvedMethod() { - return resolvedMethod; - } - - public void setResolvedMethod(ExecutableElement resolvedMethod) { - this.resolvedMethod = resolvedMethod; - } - - @Override - public String toString() { - return "Call [receiver=" + receiver + ", name=" + name + ", parameters=" + parameters + ", resolvedMethod=" + resolvedMethod + "]"; - } - - } - - public static final class Variable extends DSLExpression { - - private final DSLExpression receiver; - private final String name; - - private VariableElement resolvedVariable; - - public Variable(DSLExpression receiver, String name) { - this.receiver = receiver; - this.name = name; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Variable) { - Variable other = (Variable) obj; - return Objects.equals(receiver, other.receiver) && name.equals(other.name); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(receiver, name); - } - - public DSLExpression getReceiver() { - return receiver; - } - - public String getName() { - return name; - } - - @Override - public void accept(DSLExpressionVisitor visitor) { - if (receiver != null) { - receiver.accept(visitor); - } - visitor.visitVariable(this); - } - - @Override - public TypeMirror getResolvedType() { - return resolvedVariable != null ? resolvedVariable.asType() : null; - } - - public void setResolvedVariable(VariableElement resolvedVariable) { - this.resolvedVariable = resolvedVariable; - } - - public VariableElement getResolvedVariable() { - return resolvedVariable; - } - - @Override - public String toString() { - return "Variable [receiver=" + receiver + ", name=" + name + ", resolvedVariable=" + resolvedVariable + "]"; - } - - } - - public static final class IntLiteral extends DSLExpression { - - private final String literal; - - private int resolvedValueInt; - private TypeMirror resolvedType; - - public IntLiteral(String literal) { - this.literal = literal; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof IntLiteral) { - IntLiteral other = (IntLiteral) obj; - return resolvedValueInt == other.resolvedValueInt; - } - return false; - } - - @Override - public int hashCode() { - return resolvedValueInt; - } - - public String getLiteral() { - return literal; - } - - public int getResolvedValueInt() { - return resolvedValueInt; - } - - public void setResolvedValueInt(int resolved) { - this.resolvedValueInt = resolved; - } - - @Override - public TypeMirror getResolvedType() { - return resolvedType; - } - - public void setResolvedType(TypeMirror resolvedType) { - this.resolvedType = resolvedType; - } - - @Override - public void accept(DSLExpressionVisitor visitor) { - visitor.visitIntLiteral(this); - } - - @Override - public String toString() { - return "IntLiteral [literal=" + literal + ", resolvedValueInt=" + resolvedValueInt + ", resolvedType=" + resolvedType + "]"; - } - - } - - public abstract class AbstractDSLExpressionVisitor implements DSLExpressionVisitor { - - public void visitBinary(Binary binary) { - } - - public void visitCall(Call binary) { - } - - public void visitIntLiteral(IntLiteral binary) { - } - - public void visitNegate(Negate negate) { - } - - public void visitVariable(Variable binary) { - } - } - - public interface DSLExpressionVisitor { - - void visitBinary(Binary binary); - - void visitNegate(Negate negate); - - void visitCall(Call binary); - - void visitVariable(Variable binary); - - void visitIntLiteral(IntLiteral binary); - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpressionResolver.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/DSLExpressionResolver.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +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.dsl.processor.expression; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.DSLExpressionVisitor; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public class DSLExpressionResolver implements DSLExpressionVisitor { - - private static final List LOGIC_OPERATORS = Arrays.asList("||"); - public static final List COMPARABLE_OPERATORS = Arrays.asList("<", "<=", ">", ">="); - public static final List IDENTITY_OPERATORS = Arrays.asList("==", "!="); - private static final String CONSTRUCTOR_KEYWORD = "new"; - - private final List variables = new ArrayList<>(); - private final List methods = new ArrayList<>(); - private final ProcessorContext context; - - private DSLExpressionResolver(ProcessorContext context) { - this.context = context; - } - - public DSLExpressionResolver(ProcessorContext context, List lookupElements) { - this(context); - lookup(lookupElements); - } - - public DSLExpressionResolver copy(List prefixElements) { - DSLExpressionResolver resolver = new DSLExpressionResolver(context); - resolver.lookup(prefixElements); - resolver.variables.addAll(variables); - resolver.methods.addAll(methods); - return resolver; - } - - private void lookup(List lookupElements) { - variablesIn(variables, lookupElements, false); - methodsIn(lookupElements); - } - - private void methodsIn(List lookupElements) { - for (Element variable : lookupElements) { - ElementKind kind = variable.getKind(); - if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) { - methods.add((ExecutableElement) variable); - } - } - } - - private static void variablesIn(List variables, List lookupElements, boolean publicOnly) { - for (Element variable : lookupElements) { - ElementKind kind = variable.getKind(); - if (kind == ElementKind.LOCAL_VARIABLE || kind == ElementKind.PARAMETER || kind == ElementKind.FIELD || kind == ElementKind.ENUM_CONSTANT) { - VariableElement variableElement = (VariableElement) variable; - if (!publicOnly || variableElement.getModifiers().contains(Modifier.PUBLIC)) { - variables.add(variableElement); - } - } - } - } - - private static String getMethodName(ExecutableElement method) { - if (method.getKind() == ElementKind.CONSTRUCTOR) { - return CONSTRUCTOR_KEYWORD; - } else { - return method.getSimpleName().toString(); - } - } - - public void visitBinary(Binary binary) { - String operator = binary.getOperator(); - TypeMirror leftType = binary.getLeft().getResolvedType(); - TypeMirror rightType = binary.getRight().getResolvedType(); - if (!ElementUtils.areTypesCompatible(leftType, rightType)) { - throw new InvalidExpressionException(String.format("Incompatible operand types %s and %s.", ElementUtils.getSimpleName(leftType), ElementUtils.getSimpleName(rightType))); - } - - TypeMirror booleanType = context.getType(boolean.class); - boolean valid; - if (LOGIC_OPERATORS.contains(operator)) { - valid = ElementUtils.typeEquals(leftType, booleanType); - } else if (COMPARABLE_OPERATORS.contains(operator)) { - valid = ElementUtils.isPrimitive(leftType); - } else if (IDENTITY_OPERATORS.contains(operator)) { - valid = leftType.getKind().isPrimitive() || leftType.getKind() == TypeKind.DECLARED || leftType.getKind() == TypeKind.ARRAY; - } else { - throw new InvalidExpressionException(String.format("The operator %s is undefined.", operator)); - } - binary.setResolvedType(booleanType); - - if (!valid) { - throw new InvalidExpressionException(String.format("The operator %s is undefined for the argument type(s) %s %s.", operator, ElementUtils.getSimpleName(leftType), - ElementUtils.getSimpleName(rightType))); - } - } - - public void visitNegate(Negate negate) { - TypeMirror booleanType = context.getType(boolean.class); - TypeMirror resolvedType = negate.getResolvedType(); - if (!ElementUtils.typeEquals(resolvedType, booleanType)) { - throw new InvalidExpressionException(String.format("The operator %s is undefined for the argument type %s.", "!", ElementUtils.getSimpleName(resolvedType))); - } - } - - public void visitCall(Call call) { - List lookupMethods; - DSLExpression receiver = call.getReceiver(); - if (receiver == null) { - lookupMethods = this.methods; - } else { - TypeMirror type = receiver.getResolvedType(); - if (type.getKind() == TypeKind.DECLARED) { - type = context.reloadType(type); // ensure ECJ has the type loaded - lookupMethods = ElementFilter.methodsIn(context.getEnvironment().getElementUtils().getAllMembers((TypeElement) ((DeclaredType) type).asElement())); - } else { - lookupMethods = Collections.emptyList(); - } - } - - ExecutableElement foundWithName = null; - outer: for (ExecutableElement method : lookupMethods) { - if (getMethodName(method).equals(call.getName())) { - foundWithName = method; - - List parameters = method.getParameters(); - if (parameters.size() != call.getParameters().size()) { - continue outer; - } - - int parameterIndex = 0; - for (DSLExpression expression : call.getParameters()) { - TypeMirror sourceType = expression.getResolvedType(); - TypeMirror targetType = parameters.get(parameterIndex).asType(); - if (!ElementUtils.isAssignable(sourceType, targetType)) { - continue outer; - } - expression.setResolvedTargetType(targetType); - parameterIndex++; - } - - call.setResolvedMethod(method); - break; - } - } - if (call.getResolvedMethod() == null) { - if (foundWithName == null) { - // parameter mismatch - throw new InvalidExpressionException(String.format("The method %s is undefined for the enclosing scope.", call.getName())); - } else { - StringBuilder arguments = new StringBuilder(); - String sep = ""; - for (DSLExpression expression : call.getParameters()) { - arguments.append(sep).append(ElementUtils.getSimpleName(expression.getResolvedType())); - sep = ", "; - } - // name mismatch - throw new InvalidExpressionException(String.format("The method %s in the type %s is not applicable for the arguments %s.", // - ElementUtils.getReadableSignature(foundWithName), // - ElementUtils.getSimpleName((TypeElement) foundWithName.getEnclosingElement()), arguments.toString())); - } - } - } - - public void visitVariable(Variable variable) { - List lookupVariables; - DSLExpression receiver = variable.getReceiver(); - if (variable.getName().equals("null")) { - variable.setResolvedVariable(new CodeVariableElement(new CodeTypeMirror(TypeKind.NULL), "null")); - } else { - if (receiver == null) { - lookupVariables = this.variables; - } else { - TypeMirror type = receiver.getResolvedType(); - if (type.getKind() == TypeKind.DECLARED) { - type = context.reloadType(type); // ensure ECJ has the type loaded - lookupVariables = new ArrayList<>(); - variablesIn(lookupVariables, context.getEnvironment().getElementUtils().getAllMembers((TypeElement) ((DeclaredType) type).asElement()), true); - } else if (type.getKind() == TypeKind.ARRAY) { - lookupVariables = Arrays. asList(new CodeVariableElement(context.getType(int.class), "length")); - } else { - lookupVariables = Collections.emptyList(); - } - } - - for (VariableElement variableElement : lookupVariables) { - if (variableElement.getSimpleName().toString().equals(variable.getName())) { - variable.setResolvedVariable(variableElement); - break; - } - } - } - - if (variable.getResolvedVariable() == null) { - throw new InvalidExpressionException(String.format("%s cannot be resolved.", variable.getName())); - } - } - - public void visitIntLiteral(IntLiteral binary) { - try { - binary.setResolvedType(context.getType(int.class)); - - final int base; - final String literal; - - if (binary.getLiteral().startsWith("0x")) { - base = 16; - literal = binary.getLiteral().substring(2); - } else if (binary.getLiteral().startsWith("0b")) { - base = 2; - literal = binary.getLiteral().substring(2); - } else if (binary.getLiteral().startsWith("0")) { - base = 8; - literal = binary.getLiteral(); - } else { - base = 10; - literal = binary.getLiteral(); - } - - binary.setResolvedValueInt(Integer.parseInt(literal, base)); - } catch (NumberFormatException e) { - throw new InvalidExpressionException(String.format("Type mismatch: cannot convert from String '%s' to int", binary.getLiteral())); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Expression.atg --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Expression.atg Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +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. - */ - -/* - * This is the grammar for DSL expressions that is used to automatically generate the Parser.java and Scanner.java - * files. You can download the parser generator Coco/R from http://ssw.jku.at/coco/. Then run - * "java -jar Coco.jar Expression.atg" - */ - -COMPILER Expression - -CHARACTERS - -letter = 'A' .. 'Z' + 'a' .. 'z' + '_' + '$'. -nonZeroDigit = "123456789". -digit = '0' + nonZeroDigit . -hexDigit = "0123456789abcdefABCDEF". -octDigit = "01234567". -binaryDigit = "01". - -TOKENS - -identifier = letter {letter | digit}. -numericLiteral = "0" ( "x" { hexDigit } | "b" { binaryDigit } | { octDigit } ) | nonZeroDigit { digit }. - -PRAGMAS - -PRODUCTIONS - - -Expression -= -LogicFactor -. - - -LogicFactor -= -ComparisonFactor -[ - ("||") (. Token op = t; .) - ComparisonFactor (. result = new Binary(op.val, result, right); .) -] -. - -ComparisonFactor -= -NegateFactor -[ - ("<" | "<=" | ">" | ">=" | "==" | "!=" ) (. Token op = t; .) - NegateFactor (. result = new Binary(op.val, result, right); .) -] -. - - -NegateFactor -= (. boolean negated = false; .) -[ - "!" (. negated = true; .) -] - Factor (. result = negated ? new Negate(result) : result;.) -. - - -Factor -= (. result = null; .) - -( - MemberExpression -| - numericLiteral (. result = new IntLiteral(t.val); .) -| - "(" - Expression - ")" - -) -. - -MemberExpression -= (. result = null; .) -( - - identifier (. Variable variable = new Variable(receiver, t.val); .) - (. result = variable; .) -[ - - "(" (. List parameters = new ArrayList<>(); - DSLExpression parameter; .) - [ - Expression (. parameters.add(parameter); .) - { - "," - Expression (. parameters.add(parameter); .) - } - ] - ")" (. result = new Call(variable.getReceiver(), variable.getName(), parameters); .) -] - -) -[ - "." MemberExpression -] -. -END Expression. - - - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/InvalidExpressionException.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/InvalidExpressionException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +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.dsl.processor.expression; - -public class InvalidExpressionException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public InvalidExpressionException(String message) { - super(message); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Parser.frame --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Parser.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -/*------------------------------------------------------------------------- -Compiler Generator Coco/R, -Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz -extended by M. Loeberbauer & A. Woess, Univ. of Linz -ported from C# to Java by Wolfgang Ahorner -with improvements by Pat Terry, Rhodes University - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program 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 -for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As an exception, it is allowed to write an extension of Coco/R that is -used as a plugin in non-free software. - -If not otherwise stated, any source code generated by Coco/R (other than -Coco/R itself) does not fall under the GNU General Public License. -------------------------------------------------------------------------*/ --->begin -package com.oracle.truffle.dsl.processor.expression; - -import java.util.*; -import java.io.*; -import java.nio.charset.*; - -import com.oracle.truffle.dsl.processor.expression.DSLExpression.*; - -// Checkstyle: stop -// @formatter:off -class Parser { --->constants - static final boolean _T = true; - static final boolean _x = false; - static final int minErrDist = 2; - - public Token t; // last recognized token - public Token la; // lookahead token - int errDist = minErrDist; - - public final Scanner scanner; - public final Errors errors; - - -->declarations - public Parser(InputStream input) { - this.scanner = new Scanner(input); - errors = new Errors(); - } - - void SynErr(int n) { - if (errDist >= minErrDist) - errors.SynErr(la.line, la.col, n); - errDist = 0; - } - - public void SemErr(String msg) { - if (errDist >= minErrDist) - errors.SemErr(t.line, t.col, msg); - errDist = 0; - } - - void Get() { - for (;;) { - t = la; - la = scanner.Scan(); - if (la.kind <= maxT) { - ++errDist; - break; - } --->pragmas - la = t; - } - } - - void Expect(int n) { - if (la.kind == n) - Get(); - else { - SynErr(n); - } - } - - boolean StartOf(int s) { - return set[s][la.kind]; - } - - void ExpectWeak(int n, int follow) { - if (la.kind == n) - Get(); - else { - SynErr(n); - while (!StartOf(follow)) - Get(); - } - } - - boolean WeakSeparator(int n, int syFol, int repFol) { - int kind = la.kind; - if (kind == n) { - Get(); - return true; - } else if (StartOf(repFol)) - return false; - else { - SynErr(n); - while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) { - Get(); - kind = la.kind; - } - return StartOf(syFol); - } - } - --->productions - - private DSLExpression parseImpl() { - la = new Token(); - la.val = ""; - Get(); - DSLExpression result = -->parseRoot - return result; - } - - private static final boolean[][] set = { --->initialization - }; - - public static DSLExpression parse(InputStream input) { - Parser parser = new Parser(input); - DSLExpression result = parser.parseImpl(); - if (parser.errors.errors.size() > 0) { - StringBuilder msg = new StringBuilder(); - for (String error : parser.errors.errors) { - msg.append(error).append("\n"); - } - throw new InvalidExpressionException(msg.toString()); - } - return result; - } - - public static DSLExpression parse(String s) { - return parse(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))); - } -} // end Parser - -class Errors { - - protected final List errors = new ArrayList<>(); - public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text - - protected void printMsg(int line, int column, String msg) { - StringBuffer b = new StringBuffer(errMsgFormat); - int pos = b.indexOf("{0}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, line); - } - pos = b.indexOf("{1}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, column); - } - pos = b.indexOf("{2}"); - if (pos >= 0) - b.replace(pos, pos + 3, msg); - errors.add(b.toString()); - } - - public void SynErr(int line, int col, int n) { - String s; - switch (n) {-->errors - default: - s = "error " + n; - break; - } - printMsg(line, col, s); - } - - public void SemErr(int line, int col, String s) { - printMsg(line, col, s); - } - - public void SemErr(String s) { - errors.add(s); - } - - public void Warning(int line, int col, String s) { - printMsg(line, col, s); - } - - public void Warning(String s) { - errors.add(s); - } -} // Errors - -class FatalError extends RuntimeException { - - public static final long serialVersionUID = 1L; - - public FatalError(String s) { - super(s); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Parser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Parser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,350 +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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. - -package com.oracle.truffle.dsl.processor.expression; - -import java.io.*; -import java.nio.charset.*; -import java.util.*; - -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; - -// Checkstyle: stop -// @formatter:off -class Parser { - public static final int _EOF = 0; - public static final int _identifier = 1; - public static final int _numericLiteral = 2; - public static final int maxT = 15; - - static final boolean _T = true; - static final boolean _x = false; - static final int minErrDist = 2; - - public Token t; // last recognized token - public Token la; // lookahead token - int errDist = minErrDist; - - public final Scanner scanner; - public final Errors errors; - - - public Parser(InputStream input) { - this.scanner = new Scanner(input); - errors = new Errors(); - } - - void SynErr(int n) { - if (errDist >= minErrDist) - errors.SynErr(la.line, la.col, n); - errDist = 0; - } - - public void SemErr(String msg) { - if (errDist >= minErrDist) - errors.SemErr(t.line, t.col, msg); - errDist = 0; - } - - void Get() { - for (;;) { - t = la; - la = scanner.Scan(); - if (la.kind <= maxT) { - ++errDist; - break; - } - - la = t; - } - } - - void Expect(int n) { - if (la.kind == n) - Get(); - else { - SynErr(n); - } - } - - boolean StartOf(int s) { - return set[s][la.kind]; - } - - void ExpectWeak(int n, int follow) { - if (la.kind == n) - Get(); - else { - SynErr(n); - while (!StartOf(follow)) - Get(); - } - } - - boolean WeakSeparator(int n, int syFol, int repFol) { - int kind = la.kind; - if (kind == n) { - Get(); - return true; - } else if (StartOf(repFol)) - return false; - else { - SynErr(n); - while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) { - Get(); - kind = la.kind; - } - return StartOf(syFol); - } - } - - DSLExpression Expression() { - DSLExpression result; - result = LogicFactor(); - return result; - } - - DSLExpression LogicFactor() { - DSLExpression result; - result = ComparisonFactor(); - if (la.kind == 3) { - Get(); - Token op = t; - DSLExpression right = ComparisonFactor(); - result = new Binary(op.val, result, right); - } - return result; - } - - DSLExpression ComparisonFactor() { - DSLExpression result; - result = NegateFactor(); - if (StartOf(1)) { - switch (la.kind) { - case 4: { - Get(); - break; - } - case 5: { - Get(); - break; - } - case 6: { - Get(); - break; - } - case 7: { - Get(); - break; - } - case 8: { - Get(); - break; - } - case 9: { - Get(); - break; - } - } - Token op = t; - DSLExpression right = NegateFactor(); - result = new Binary(op.val, result, right); - } - return result; - } - - DSLExpression NegateFactor() { - DSLExpression result; - boolean negated = false; - if (la.kind == 10) { - Get(); - negated = true; - } - result = Factor(); - result = negated ? new Negate(result) : result; - return result; - } - - DSLExpression Factor() { - DSLExpression result; - result = null; - if (la.kind == 1) { - result = MemberExpression(result); - } else if (la.kind == 2) { - Get(); - result = new IntLiteral(t.val); - } else if (la.kind == 11) { - Get(); - result = Expression(); - Expect(12); - } else SynErr(16); - return result; - } - - DSLExpression MemberExpression(DSLExpression receiver) { - DSLExpression result; - result = null; - Expect(1); - Variable variable = new Variable(receiver, t.val); - result = variable; - if (la.kind == 11) { - Get(); - List parameters = new ArrayList<>(); - DSLExpression parameter; - if (StartOf(2)) { - parameter = Expression(); - parameters.add(parameter); - while (la.kind == 13) { - Get(); - parameter = Expression(); - parameters.add(parameter); - } - } - Expect(12); - result = new Call(variable.getReceiver(), variable.getName(), parameters); - } - if (la.kind == 14) { - Get(); - result = MemberExpression(result); - } - return result; - } - - - - private DSLExpression parseImpl() { - la = new Token(); - la.val = ""; - Get(); - DSLExpression result = Expression(); - Expect(0); - - return result; - } - - private static final boolean[][] set = { - {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x}, - {_x,_x,_x,_x, _T,_T,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x}, - {_x,_T,_T,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x} - - }; - - public static DSLExpression parse(InputStream input) { - Parser parser = new Parser(input); - DSLExpression result = parser.parseImpl(); - if (parser.errors.errors.size() > 0) { - StringBuilder msg = new StringBuilder(); - for (String error : parser.errors.errors) { - msg.append(error).append("\n"); - } - throw new InvalidExpressionException(msg.toString()); - } - return result; - } - - public static DSLExpression parse(String s) { - return parse(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))); - } -} // end Parser - -class Errors { - - protected final List errors = new ArrayList<>(); - public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text - - protected void printMsg(int line, int column, String msg) { - StringBuffer b = new StringBuffer(errMsgFormat); - int pos = b.indexOf("{0}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, line); - } - pos = b.indexOf("{1}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, column); - } - pos = b.indexOf("{2}"); - if (pos >= 0) - b.replace(pos, pos + 3, msg); - errors.add(b.toString()); - } - - public void SynErr(int line, int col, int n) { - String s; - switch (n) { - case 0: s = "EOF expected"; break; - case 1: s = "identifier expected"; break; - case 2: s = "numericLiteral expected"; break; - case 3: s = "\"||\" expected"; break; - case 4: s = "\"<\" expected"; break; - case 5: s = "\"<=\" expected"; break; - case 6: s = "\">\" expected"; break; - case 7: s = "\">=\" expected"; break; - case 8: s = "\"==\" expected"; break; - case 9: s = "\"!=\" expected"; break; - case 10: s = "\"!\" expected"; break; - case 11: s = "\"(\" expected"; break; - case 12: s = "\")\" expected"; break; - case 13: s = "\",\" expected"; break; - case 14: s = "\".\" expected"; break; - case 15: s = "??? expected"; break; - case 16: s = "invalid Factor"; break; - default: - s = "error " + n; - break; - } - printMsg(line, col, s); - } - - public void SemErr(int line, int col, String s) { - printMsg(line, col, s); - } - - public void SemErr(String s) { - errors.add(s); - } - - public void Warning(int line, int col, String s) { - printMsg(line, col, s); - } - - public void Warning(String s) { - errors.add(s); - } -} // Errors - -class FatalError extends RuntimeException { - - public static final long serialVersionUID = 1L; - - public FatalError(String s) { - super(s); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Scanner.frame --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Scanner.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,495 +0,0 @@ -/*------------------------------------------------------------------------- -Compiler Generator Coco/R, -Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz -extended by M. Loeberbauer & A. Woess, Univ. of Linz -ported from C# to Java by Wolfgang Ahorner -with improvements by Pat Terry, Rhodes University - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program 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 -for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As an exception, it is allowed to write an extension of Coco/R that is -used as a plugin in non-free software. - -If not otherwise stated, any source code generated by Coco/R (other than -Coco/R itself) does not fall under the GNU General Public License. -------------------------------------------------------------------------*/ --->begin -package com.oracle.truffle.dsl.processor.expression; - -import java.io.InputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Map; -import java.util.HashMap; - -// Checkstyle: stop -// @formatter:off -class Token { - - public int kind; // token kind - public int pos; // token position in bytes in the source text (starting at 0) - public int charPos; // token position in characters in the source text (starting at 0) - public int col; // token column (starting at 1) - public int line; // token line (starting at 1) - public String val; // token value - public Token next; // ML 2005-03-11 Peek tokens are kept in linked list -} - -// ----------------------------------------------------------------------------------- -// Buffer -// ----------------------------------------------------------------------------------- -class Buffer { - - // This Buffer supports the following cases: - // 1) seekable stream (file) - // a) whole stream in buffer - // b) part of stream in buffer - // 2) non seekable stream (network, console) - - public static final int EOF = Character.MAX_VALUE + 1; - private static final int MIN_BUFFER_LENGTH = 1024; // 1KB - private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB - private byte[] buf; // input buffer - private int bufStart; // position of first byte in buffer relative to input stream - private int bufLen; // length of buffer - private int fileLen; // length of input stream (may change if stream is no file) - private int bufPos; // current position in buffer - private RandomAccessFile file; // input stream (seekable) - private InputStream stream; // growing input stream (e.g.: console, network) - - public Buffer(InputStream s) { - stream = s; - fileLen = bufLen = bufStart = bufPos = 0; - buf = new byte[MIN_BUFFER_LENGTH]; - } - - public Buffer(String fileName) { - try { - file = new RandomAccessFile(fileName, "r"); - fileLen = (int) file.length(); - bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH); - buf = new byte[bufLen]; - bufStart = Integer.MAX_VALUE; // nothing in buffer so far - if (fileLen > 0) - setPos(0); // setup buffer to position 0 (start) - else - bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid - if (bufLen == fileLen) - Close(); - } catch (IOException e) { - throw new FatalError("Could not open file " + fileName); - } - } - - // don't use b after this call anymore - // called in UTF8Buffer constructor - protected Buffer(Buffer b) { - buf = b.buf; - bufStart = b.bufStart; - bufLen = b.bufLen; - fileLen = b.fileLen; - bufPos = b.bufPos; - file = b.file; - stream = b.stream; - // keep finalize from closing the file - b.file = null; - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - Close(); - } - - protected void Close() { - if (file != null) { - try { - file.close(); - file = null; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } - } - - public int Read() { - if (bufPos < bufLen) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (getPos() < fileLen) { - setPos(getPos()); // shift buffer start to pos - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (stream != null && ReadNextStreamChunk() > 0) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else { - return EOF; - } - } - - public int Peek() { - int curPos = getPos(); - int ch = Read(); - setPos(curPos); - return ch; - } - - // beg .. begin, zero-based, inclusive, in byte - // end .. end, zero-based, exclusive, in byte - public String GetString(int beg, int end) { - int len = 0; - char[] buffer = new char[end - beg]; - int oldPos = getPos(); - setPos(beg); - while (getPos() < end) - buffer[len++] = (char) Read(); - setPos(oldPos); - return new String(buffer, 0, len); - } - - public int getPos() { - return bufPos + bufStart; - } - - public void setPos(int value) { - if (value >= fileLen && stream != null) { - // Wanted position is after buffer and the stream - // is not seek-able e.g. network or console, - // thus we have to read the stream manually till - // the wanted position is in sight. - while (value >= fileLen && ReadNextStreamChunk() > 0) { - // nothing to do... - } - } - - if (value < 0 || value > fileLen) { - throw new FatalError("buffer out of bounds access, position: " + value); - } - - if (value >= bufStart && value < bufStart + bufLen) { // already in buffer - bufPos = value - bufStart; - } else if (file != null) { // must be swapped in - try { - file.seek(value); - bufLen = file.read(buf); - bufStart = value; - bufPos = 0; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } else { - // set the position to the end of the file, Pos will return fileLen. - bufPos = fileLen - bufStart; - } - } - - // Read the next chunk of bytes from the stream, increases the buffer - // if needed and updates the fields fileLen and bufLen. - // Returns the number of bytes read. - private int ReadNextStreamChunk() { - int free = buf.length - bufLen; - if (free == 0) { - // in the case of a growing input stream - // we can neither seek in the stream, nor can we - // foresee the maximum length, thus we must adapt - // the buffer size on demand. - byte[] newBuf = new byte[bufLen * 2]; - System.arraycopy(buf, 0, newBuf, 0, bufLen); - buf = newBuf; - free = bufLen; - } - - int read; - try { - read = stream.read(buf, bufLen, free); - } catch (IOException ioex) { - throw new FatalError(ioex.getMessage()); - } - - if (read > 0) { - fileLen = bufLen = (bufLen + read); - return read; - } - // end of stream reached - return 0; - } -} - -// ----------------------------------------------------------------------------------- -// UTF8Buffer -// ----------------------------------------------------------------------------------- -class UTF8Buffer extends Buffer { - - UTF8Buffer(Buffer b) { - super(b); - } - - @Override - public int Read() { - int ch; - do { - ch = super.Read(); - // until we find a utf8 start (0xxxxxxx or 11xxxxxx) - } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF)); - if (ch < 128 || ch == EOF) { - // nothing to do, first 127 chars are the same in ascii and utf8 - // 0xxxxxxx or end of file character - } else if ((ch & 0xF0) == 0xF0) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x07; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = super.Read(); - int c4 = ch & 0x3F; - ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4; - } else if ((ch & 0xE0) == 0xE0) { - // 1110xxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x0F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = (((c1 << 6) | c2) << 6) | c3; - } else if ((ch & 0xC0) == 0xC0) { - // 110xxxxx 10xxxxxx - int c1 = ch & 0x1F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = (c1 << 6) | c2; - } - return ch; - } -} - -// ----------------------------------------------------------------------------------- -// StartStates -- maps characters to start states of tokens -// ----------------------------------------------------------------------------------- -class StartStates { - - private static class Elem { - - public int key, val; - public Elem next; - - public Elem(int key, int val) { - this.key = key; - this.val = val; - } - } - - private Elem[] tab = new Elem[128]; - - public void set(int key, int val) { - Elem e = new Elem(key, val); - int k = key % 128; - e.next = tab[k]; - tab[k] = e; - } - - public int state(int key) { - Elem e = tab[key % 128]; - while (e != null && e.key != key) - e = e.next; - return e == null ? 0 : e.val; - } -} - -// ----------------------------------------------------------------------------------- -// Scanner -// ----------------------------------------------------------------------------------- -@SuppressWarnings({"rawtypes"}) -public class Scanner { - - static final char EOL = '\n'; - static final int eofSym = 0; --->declarations - - public Buffer buffer; // scanner buffer - - Token t; // current token - int ch; // current input character - int pos; // byte position of current character - int charPos; // position by unicode characters starting with 0 - int col; // column number of current character - int line; // line number of current character - int oldEols; // EOLs that appeared in a comment; - static final StartStates start; // maps initial token character to start state - static final Map literals; // maps literal strings to literal kinds - - Token tokens; // list of tokens already peeked (first token is a dummy) - Token pt; // current peek token - - char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged - int tlen; // length of current token - - static { - start = new StartStates(); - literals = new HashMap(); --->initialization - } - - public Scanner(String fileName) { - buffer = new Buffer(fileName); - Init(); - } - - public Scanner(InputStream s) { - buffer = new Buffer(s); - Init(); - } - - void Init() { - pos = -1; - line = 1; - col = 0; - charPos = -1; - oldEols = 0; - NextCh(); - if (ch == 0xEF) { // check optional byte order mark for UTF-8 - NextCh(); - int ch1 = ch; - NextCh(); - int ch2 = ch; - if (ch1 != 0xBB || ch2 != 0xBF) { - throw new FatalError("Illegal byte order mark at start of file"); - } - buffer = new UTF8Buffer(buffer); - col = 0; - charPos = -1; - NextCh(); - } - pt = tokens = new Token(); // first token is a dummy - } - - void NextCh() { - if (oldEols > 0) { - ch = EOL; - oldEols--; - } else { - pos = buffer.getPos(); - // buffer reads unicode chars, if UTF8 has been detected - ch = buffer.Read(); - col++; - charPos++; - // replace isolated '\r' by '\n' in order to make - // eol handling uniform across Windows, Unix and Mac - if (ch == '\r' && buffer.Peek() != '\n') - ch = EOL; - if (ch == EOL) { - line++; - col = 0; - } - } --->casing - } - - void AddCh() { - if (tlen >= tval.length) { - char[] newBuf = new char[2 * tval.length]; - System.arraycopy(tval, 0, newBuf, 0, tval.length); - tval = newBuf; - } - if (ch != Buffer.EOF) { --->casing2 - NextCh(); - } - } - --->comments - - void CheckLiteral() { - String val = t.val; --->casing3 - Object kind = literals.get(val); - if (kind != null) { - t.kind = ((Integer) kind).intValue(); - } - } - - Token NextToken() { - while (ch == ' ' || --->scan1 - ) NextCh(); --->scan2 - int recKind = noSym; - int recEnd = pos; - t = new Token(); - t.pos = pos; - t.col = col; - t.line = line; - t.charPos = charPos; - int state = start.state(ch); - tlen = 0; - AddCh(); - - loop: for (;;) { - switch (state) { - case -1: { - t.kind = eofSym; - break loop; - } // NextCh already done - case 0: { - if (recKind != noSym) { - tlen = recEnd - t.pos; - SetScannerBehindT(); - } - t.kind = recKind; - break loop; - } // NextCh already done --->scan3 - } - } - t.val = new String(tval, 0, tlen); - return t; - } - - private void SetScannerBehindT() { - buffer.setPos(t.pos); - NextCh(); - line = t.line; - col = t.col; - charPos = t.charPos; - for (int i = 0; i < tlen; i++) - NextCh(); - } - - // get the next token (possibly a token already seen during peeking) - public Token Scan() { - if (tokens.next == null) { - return NextToken(); - } else { - pt = tokens = tokens.next; - return tokens; - } - } - - // get the next token, ignore pragmas - public Token Peek() { - do { - if (pt.next == null) { - pt.next = NextToken(); - } - pt = pt.next; - } while (pt.kind > maxT); // skip pragmas - - return pt; - } - - // make sure that peeking starts at current scan position - public void ResetPeek() { - pt = tokens; - } - -} // end Scanner diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Scanner.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/expression/Scanner.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,570 +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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. - -package com.oracle.truffle.dsl.processor.expression; - -import java.io.*; -import java.util.*; - -// Checkstyle: stop -// @formatter:off -class Token { - - public int kind; // token kind - public int pos; // token position in bytes in the source text (starting at 0) - public int charPos; // token position in characters in the source text (starting at 0) - public int col; // token column (starting at 1) - public int line; // token line (starting at 1) - public String val; // token value - public Token next; // ML 2005-03-11 Peek tokens are kept in linked list -} - -// ----------------------------------------------------------------------------------- -// Buffer -// ----------------------------------------------------------------------------------- -class Buffer { - - // This Buffer supports the following cases: - // 1) seekable stream (file) - // a) whole stream in buffer - // b) part of stream in buffer - // 2) non seekable stream (network, console) - - public static final int EOF = Character.MAX_VALUE + 1; - private static final int MIN_BUFFER_LENGTH = 1024; // 1KB - private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB - private byte[] buf; // input buffer - private int bufStart; // position of first byte in buffer relative to input stream - private int bufLen; // length of buffer - private int fileLen; // length of input stream (may change if stream is no file) - private int bufPos; // current position in buffer - private RandomAccessFile file; // input stream (seekable) - private InputStream stream; // growing input stream (e.g.: console, network) - - public Buffer(InputStream s) { - stream = s; - fileLen = bufLen = bufStart = bufPos = 0; - buf = new byte[MIN_BUFFER_LENGTH]; - } - - public Buffer(String fileName) { - try { - file = new RandomAccessFile(fileName, "r"); - fileLen = (int) file.length(); - bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH); - buf = new byte[bufLen]; - bufStart = Integer.MAX_VALUE; // nothing in buffer so far - if (fileLen > 0) - setPos(0); // setup buffer to position 0 (start) - else - bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid - if (bufLen == fileLen) - Close(); - } catch (IOException e) { - throw new FatalError("Could not open file " + fileName); - } - } - - // don't use b after this call anymore - // called in UTF8Buffer constructor - protected Buffer(Buffer b) { - buf = b.buf; - bufStart = b.bufStart; - bufLen = b.bufLen; - fileLen = b.fileLen; - bufPos = b.bufPos; - file = b.file; - stream = b.stream; - // keep finalize from closing the file - b.file = null; - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - Close(); - } - - protected void Close() { - if (file != null) { - try { - file.close(); - file = null; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } - } - - public int Read() { - if (bufPos < bufLen) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (getPos() < fileLen) { - setPos(getPos()); // shift buffer start to pos - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (stream != null && ReadNextStreamChunk() > 0) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else { - return EOF; - } - } - - public int Peek() { - int curPos = getPos(); - int ch = Read(); - setPos(curPos); - return ch; - } - - // beg .. begin, zero-based, inclusive, in byte - // end .. end, zero-based, exclusive, in byte - public String GetString(int beg, int end) { - int len = 0; - char[] buffer = new char[end - beg]; - int oldPos = getPos(); - setPos(beg); - while (getPos() < end) - buffer[len++] = (char) Read(); - setPos(oldPos); - return new String(buffer, 0, len); - } - - public int getPos() { - return bufPos + bufStart; - } - - public void setPos(int value) { - if (value >= fileLen && stream != null) { - // Wanted position is after buffer and the stream - // is not seek-able e.g. network or console, - // thus we have to read the stream manually till - // the wanted position is in sight. - while (value >= fileLen && ReadNextStreamChunk() > 0) { - // nothing to do... - } - } - - if (value < 0 || value > fileLen) { - throw new FatalError("buffer out of bounds access, position: " + value); - } - - if (value >= bufStart && value < bufStart + bufLen) { // already in buffer - bufPos = value - bufStart; - } else if (file != null) { // must be swapped in - try { - file.seek(value); - bufLen = file.read(buf); - bufStart = value; - bufPos = 0; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } else { - // set the position to the end of the file, Pos will return fileLen. - bufPos = fileLen - bufStart; - } - } - - // Read the next chunk of bytes from the stream, increases the buffer - // if needed and updates the fields fileLen and bufLen. - // Returns the number of bytes read. - private int ReadNextStreamChunk() { - int free = buf.length - bufLen; - if (free == 0) { - // in the case of a growing input stream - // we can neither seek in the stream, nor can we - // foresee the maximum length, thus we must adapt - // the buffer size on demand. - byte[] newBuf = new byte[bufLen * 2]; - System.arraycopy(buf, 0, newBuf, 0, bufLen); - buf = newBuf; - free = bufLen; - } - - int read; - try { - read = stream.read(buf, bufLen, free); - } catch (IOException ioex) { - throw new FatalError(ioex.getMessage()); - } - - if (read > 0) { - fileLen = bufLen = (bufLen + read); - return read; - } - // end of stream reached - return 0; - } -} - -// ----------------------------------------------------------------------------------- -// UTF8Buffer -// ----------------------------------------------------------------------------------- -class UTF8Buffer extends Buffer { - - UTF8Buffer(Buffer b) { - super(b); - } - - @Override - public int Read() { - int ch; - do { - ch = super.Read(); - // until we find a utf8 start (0xxxxxxx or 11xxxxxx) - } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF)); - if (ch < 128 || ch == EOF) { - // nothing to do, first 127 chars are the same in ascii and utf8 - // 0xxxxxxx or end of file character - } else if ((ch & 0xF0) == 0xF0) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x07; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = super.Read(); - int c4 = ch & 0x3F; - ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4; - } else if ((ch & 0xE0) == 0xE0) { - // 1110xxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x0F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = (((c1 << 6) | c2) << 6) | c3; - } else if ((ch & 0xC0) == 0xC0) { - // 110xxxxx 10xxxxxx - int c1 = ch & 0x1F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = (c1 << 6) | c2; - } - return ch; - } -} - -// ----------------------------------------------------------------------------------- -// StartStates -- maps characters to start states of tokens -// ----------------------------------------------------------------------------------- -class StartStates { - - private static class Elem { - - public int key, val; - public Elem next; - - public Elem(int key, int val) { - this.key = key; - this.val = val; - } - } - - private Elem[] tab = new Elem[128]; - - public void set(int key, int val) { - Elem e = new Elem(key, val); - int k = key % 128; - e.next = tab[k]; - tab[k] = e; - } - - public int state(int key) { - Elem e = tab[key % 128]; - while (e != null && e.key != key) - e = e.next; - return e == null ? 0 : e.val; - } -} - -// ----------------------------------------------------------------------------------- -// Scanner -// ----------------------------------------------------------------------------------- -@SuppressWarnings({"rawtypes"}) -public class Scanner { - - static final char EOL = '\n'; - static final int eofSym = 0; - static final int maxT = 15; - static final int noSym = 15; - - - public Buffer buffer; // scanner buffer - - Token t; // current token - int ch; // current input character - int pos; // byte position of current character - int charPos; // position by unicode characters starting with 0 - int col; // column number of current character - int line; // line number of current character - int oldEols; // EOLs that appeared in a comment; - static final StartStates start; // maps initial token character to start state - static final Map literals; // maps literal strings to literal kinds - - Token tokens; // list of tokens already peeked (first token is a dummy) - Token pt; // current peek token - - char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged - int tlen; // length of current token - - static { - start = new StartStates(); - literals = new HashMap(); - for (int i = 36; i <= 36; ++i) start.set(i, 1); - for (int i = 65; i <= 90; ++i) start.set(i, 1); - for (int i = 95; i <= 95; ++i) start.set(i, 1); - for (int i = 97; i <= 122; ++i) start.set(i, 1); - for (int i = 49; i <= 57; ++i) start.set(i, 6); - start.set(48, 2); - start.set(124, 7); - start.set(60, 18); - start.set(62, 19); - start.set(61, 11); - start.set(33, 20); - start.set(40, 14); - start.set(41, 15); - start.set(44, 16); - start.set(46, 17); - start.set(Buffer.EOF, -1); - - } - - public Scanner(String fileName) { - buffer = new Buffer(fileName); - Init(); - } - - public Scanner(InputStream s) { - buffer = new Buffer(s); - Init(); - } - - void Init() { - pos = -1; - line = 1; - col = 0; - charPos = -1; - oldEols = 0; - NextCh(); - if (ch == 0xEF) { // check optional byte order mark for UTF-8 - NextCh(); - int ch1 = ch; - NextCh(); - int ch2 = ch; - if (ch1 != 0xBB || ch2 != 0xBF) { - throw new FatalError("Illegal byte order mark at start of file"); - } - buffer = new UTF8Buffer(buffer); - col = 0; - charPos = -1; - NextCh(); - } - pt = tokens = new Token(); // first token is a dummy - } - - void NextCh() { - if (oldEols > 0) { - ch = EOL; - oldEols--; - } else { - pos = buffer.getPos(); - // buffer reads unicode chars, if UTF8 has been detected - ch = buffer.Read(); - col++; - charPos++; - // replace isolated '\r' by '\n' in order to make - // eol handling uniform across Windows, Unix and Mac - if (ch == '\r' && buffer.Peek() != '\n') - ch = EOL; - if (ch == EOL) { - line++; - col = 0; - } - } - - } - - void AddCh() { - if (tlen >= tval.length) { - char[] newBuf = new char[2 * tval.length]; - System.arraycopy(tval, 0, newBuf, 0, tval.length); - tval = newBuf; - } - if (ch != Buffer.EOF) { - tval[tlen++] = (char)ch; - - NextCh(); - } - } - - - - void CheckLiteral() { - String val = t.val; - - Object kind = literals.get(val); - if (kind != null) { - t.kind = ((Integer) kind).intValue(); - } - } - - Token NextToken() { - while (ch == ' ' || - false - ) NextCh(); - - int recKind = noSym; - int recEnd = pos; - t = new Token(); - t.pos = pos; - t.col = col; - t.line = line; - t.charPos = charPos; - int state = start.state(ch); - tlen = 0; - AddCh(); - - loop: for (;;) { - switch (state) { - case -1: { - t.kind = eofSym; - break loop; - } // NextCh already done - case 0: { - if (recKind != noSym) { - tlen = recEnd - t.pos; - SetScannerBehindT(); - } - t.kind = recKind; - break loop; - } // NextCh already done - case 1: - recEnd = pos; recKind = 1; - if (ch == '$' || ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;} - else {t.kind = 1; break loop;} - case 2: - recEnd = pos; recKind = 2; - if (ch >= '0' && ch <= '7') {AddCh(); state = 5; break;} - else if (ch == 'x') {AddCh(); state = 3; break;} - else if (ch == 'b') {AddCh(); state = 4; break;} - else {t.kind = 2; break loop;} - case 3: - recEnd = pos; recKind = 2; - if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {AddCh(); state = 3; break;} - else {t.kind = 2; break loop;} - case 4: - recEnd = pos; recKind = 2; - if (ch >= '0' && ch <= '1') {AddCh(); state = 4; break;} - else {t.kind = 2; break loop;} - case 5: - recEnd = pos; recKind = 2; - if (ch >= '0' && ch <= '7') {AddCh(); state = 5; break;} - else {t.kind = 2; break loop;} - case 6: - recEnd = pos; recKind = 2; - if (ch >= '0' && ch <= '9') {AddCh(); state = 6; break;} - else {t.kind = 2; break loop;} - case 7: - if (ch == '|') {AddCh(); state = 8; break;} - else {state = 0; break;} - case 8: - {t.kind = 3; break loop;} - case 9: - {t.kind = 5; break loop;} - case 10: - {t.kind = 7; break loop;} - case 11: - if (ch == '=') {AddCh(); state = 12; break;} - else {state = 0; break;} - case 12: - {t.kind = 8; break loop;} - case 13: - {t.kind = 9; break loop;} - case 14: - {t.kind = 11; break loop;} - case 15: - {t.kind = 12; break loop;} - case 16: - {t.kind = 13; break loop;} - case 17: - {t.kind = 14; break loop;} - case 18: - recEnd = pos; recKind = 4; - if (ch == '=') {AddCh(); state = 9; break;} - else {t.kind = 4; break loop;} - case 19: - recEnd = pos; recKind = 6; - if (ch == '=') {AddCh(); state = 10; break;} - else {t.kind = 6; break loop;} - case 20: - recEnd = pos; recKind = 10; - if (ch == '=') {AddCh(); state = 13; break;} - else {t.kind = 10; break loop;} - - } - } - t.val = new String(tval, 0, tlen); - return t; - } - - private void SetScannerBehindT() { - buffer.setPos(t.pos); - NextCh(); - line = t.line; - col = t.col; - charPos = t.charPos; - for (int i = 0; i < tlen; i++) - NextCh(); - } - - // get the next token (possibly a token already seen during peeking) - public Token Scan() { - if (tokens.next == null) { - return NextToken(); - } else { - pt = tokens = tokens.next; - return tokens; - } - } - - // get the next token, ignore pragmas - public Token Peek() { - do { - if (pt.next == null) { - pt.next = NextToken(); - } - pt = pt.next; - } while (pt.kind > maxT); // skip pragmas - - return pt; - } - - // make sure that peeking starts at current scan position - public void ResetPeek() { - pt = tokens; - } - -} // end Scanner diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/CodeTypeElementFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/CodeTypeElementFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +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.dsl.processor.generator; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public abstract class CodeTypeElementFactory { - - public abstract CodeTypeElement create(ProcessorContext context, M m); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/DSLExpressionGenerator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +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.dsl.processor.generator; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Binary; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Call; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.DSLExpressionVisitor; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.IntLiteral; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; -import com.oracle.truffle.dsl.processor.java.model.*; - -public class DSLExpressionGenerator implements DSLExpressionVisitor { - - private final Map bindings; - private final CodeTree root; - private final Deque stack = new ArrayDeque<>(); - - public DSLExpressionGenerator(CodeTree root, Map bindings) { - this.bindings = bindings; - this.root = root; - } - - public void visitBinary(Binary binary) { - CodeTree right = stack.pop(); - CodeTree left = stack.pop(); - stack.push(combine(left, string(" " + binary.getOperator() + " "), right)); - } - - public void visitCall(Call call) { - ExecutableElement method = call.getResolvedMethod(); - CodeTree[] parameters = new CodeTree[method.getParameters().size()]; - for (int i = 0; i < parameters.length; i++) { - parameters[parameters.length - i - 1] = pop(); - } - - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - if (call.getResolvedMethod().getKind() == ElementKind.CONSTRUCTOR) { - builder.startNew(call.getResolvedType()); - } else if (call.getReceiver() == null) { - if (isStatic(method)) { - builder.startStaticCall(method); - } else { - if (root != null) { - builder.tree(root).string("."); - } - builder.startCall(method.getSimpleName().toString()); - } - } else { - if (isStatic(method)) { - throw new AssertionError("Static calls must not have receivers."); - } - builder.startCall(pop(), method.getSimpleName().toString()); - } - for (CodeTree parameter : parameters) { - builder.tree(parameter); - } - builder.end(); - - push(builder.build()); - } - - public void visitIntLiteral(IntLiteral binary) { - push(string(binary.getLiteral())); - } - - public void visitNegate(Negate negate) { - push(combine(string("!"), combine(string("("), pop(), string(")")))); - } - - public void visitVariable(Variable variable) { - VariableElement resolvedVariable = variable.getResolvedVariable(); - CodeTree tree; - if (variable.getResolvedType().getKind() == TypeKind.NULL) { - tree = CodeTreeBuilder.singleString("null"); - } else if (variable.getReceiver() == null) { - - if (isStatic(resolvedVariable)) { - tree = staticReference(resolvedVariable); - } else { - tree = bindings.get(variable); - boolean bound = true; - if (tree == null) { - tree = string(resolvedVariable.getSimpleName().toString()); - bound = false; - } - if (root != null && !bound) { - tree = combine(root, string("."), tree); - } - } - } else { - if (isStatic(resolvedVariable)) { - throw new AssertionError("Static variables cannot have receivers."); - } - tree = combine(pop(), string("."), string(resolvedVariable.getSimpleName().toString())); - } - push(tree); - } - - private static boolean isStatic(Element element) { - return element.getModifiers().contains(Modifier.STATIC); - } - - private static CodeTree combine(CodeTree tree1, CodeTree tree2) { - return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).end().build(); - } - - private static CodeTree combine(CodeTree tree1, CodeTree tree2, CodeTree tree3) { - return new CodeTreeBuilder(null).startGroup().tree(tree1).tree(tree2).tree(tree3).end().build(); - } - - private static CodeTree string(String s) { - return CodeTreeBuilder.singleString(s); - } - - private static CodeTree staticReference(VariableElement var) { - return CodeTreeBuilder.createBuilder().staticReference(var.getEnclosingElement().asType(), var.getSimpleName().toString()).build(); - } - - private void push(CodeTree tree) { - stack.push(tree); - } - - private CodeTree pop() { - return stack.pop(); - } - - public static CodeTree write(DSLExpression expression, CodeTree root, Map bindings) { - DSLExpressionGenerator writer = new DSLExpressionGenerator(root, bindings); - expression.accept(writer); - return combine(string("("), writer.pop(), string(")")); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/GeneratorUtils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/GeneratorUtils.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +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.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.DSLOptions.TypeBoxingOptimization; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class GeneratorUtils { - - public static CodeTree createTransferToInterpreterAndInvalidate() { - ProcessorContext context = ProcessorContext.getInstance(); - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startStatement().startStaticCall(context.getType(CompilerDirectives.class), "transferToInterpreterAndInvalidate").end().end(); - return builder.build(); - } - - public static CodeExecutableElement createConstructorUsingFields(Set modifiers, CodeTypeElement clazz) { - TypeElement superClass = fromTypeMirror(clazz.getSuperclass()); - ExecutableElement constructor = findConstructor(superClass); - return createConstructorUsingFields(modifiers, clazz, constructor); - } - - public static CodeExecutableElement createConstructorUsingFields(Set modifiers, CodeTypeElement clazz, ExecutableElement constructor) { - CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString()); - CodeTreeBuilder builder = method.createBuilder(); - if (constructor != null && constructor.getParameters().size() > 0) { - builder.startStatement(); - builder.startSuperCall(); - for (VariableElement parameter : constructor.getParameters()) { - method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString())); - builder.string(parameter.getSimpleName().toString()); - } - builder.end(); // super - builder.end(); // statement - } - - for (VariableElement field : clazz.getFields()) { - if (field.getModifiers().contains(STATIC)) { - continue; - } - String fieldName = field.getSimpleName().toString(); - method.addParameter(new CodeVariableElement(field.asType(), fieldName)); - builder.startStatement(); - builder.string("this."); - builder.string(fieldName); - builder.string(" = "); - builder.string(fieldName); - builder.end(); // statement - } - - return method; - } - - public static boolean isTypeBoxingOptimized(TypeBoxingOptimization boxing, TypeMirror type) { - switch (boxing) { - case NONE: - return false; - case ALWAYS: - return !ElementUtils.isObject(type) && !ElementUtils.isVoid(type); - case PRIMITIVE: - return ElementUtils.isPrimitive(type); - default: - throw new AssertionError(); - } - } - - private static ExecutableElement findConstructor(TypeElement clazz) { - List constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements()); - if (constructors.isEmpty()) { - return null; - } else { - return constructors.get(0); - } - } - - public static CodeExecutableElement createSuperConstructor(ProcessorContext context, TypeElement type, ExecutableElement element) { - if (element.getModifiers().contains(Modifier.PRIVATE)) { - return null; - } - CodeExecutableElement executable = CodeExecutableElement.clone(context.getEnvironment(), element); - executable.setReturnType(null); - executable.setSimpleName(CodeNames.of(type.getSimpleName().toString())); - CodeTreeBuilder b = executable.createBuilder(); - b.startStatement(); - b.startSuperCall(); - for (VariableElement v : element.getParameters()) { - b.string(v.getSimpleName().toString()); - } - b.end(); - b.end(); - - return executable; - } - - public static CodeTypeElement createClass(Template sourceModel, TemplateMethod sourceMethod, Set modifiers, String simpleName, TypeMirror superType) { - TypeElement templateType = sourceModel.getTemplateType(); - - ProcessorContext context = ProcessorContext.getInstance(); - - PackageElement pack = context.getEnvironment().getElementUtils().getPackageOf(templateType); - CodeTypeElement clazz = new CodeTypeElement(modifiers, ElementKind.CLASS, pack, simpleName); - TypeMirror resolvedSuperType = superType; - if (resolvedSuperType == null) { - resolvedSuperType = context.getType(Object.class); - } - clazz.setSuperClass(resolvedSuperType); - - CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) context.getType(GeneratedBy.class)); - generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType())); - if (sourceMethod != null && sourceMethod.getMethod() != null) { - generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(sourceMethod.createReferenceName())); - } - - clazz.addAnnotationMirror(generatedByAnnotation); - return clazz; - } - - public static List findUserConstructors(TypeMirror nodeType) { - List constructors = new ArrayList<>(); - for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) { - if (constructor.getModifiers().contains(PRIVATE)) { - continue; - } - if (isCopyConstructor(constructor)) { - continue; - } - constructors.add(constructor); - } - - if (constructors.isEmpty()) { - constructors.add(new CodeExecutableElement(null, ElementUtils.getSimpleName(nodeType))); - } - - return constructors; - } - - public static boolean isCopyConstructor(ExecutableElement element) { - if (element.getParameters().size() != 1) { - return false; - } - VariableElement var = element.getParameters().get(0); - TypeElement enclosingType = ElementUtils.findNearestEnclosingType(var); - if (ElementUtils.typeEquals(var.asType(), enclosingType.asType())) { - return true; - } - List types = ElementUtils.getDirectSuperTypes(enclosingType); - for (TypeElement type : types) { - if (!(type instanceof CodeTypeElement)) { - // no copy constructors which are not generated types - return false; - } - - if (ElementUtils.typeEquals(var.asType(), type.asType())) { - return true; - } - } - return false; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/ImplicitCastNodeFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/ImplicitCastNodeFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +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.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.generator.GeneratorUtils.*; -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class ImplicitCastNodeFactory { - - private final ProcessorContext context; - private final TypeMirror forType; - private final TypeSystemData typeSystem; - private final DSLOptions options; - private final List sourceTypes; - - public ImplicitCastNodeFactory(ProcessorContext context, TypeSystemData typeSystem, TypeMirror forType) { - this.context = context; - this.forType = forType; - this.typeSystem = typeSystem; - this.options = typeSystem.getOptions(); - this.sourceTypes = typeSystem.lookupSourceTypes(forType); - } - - public static String typeName(TypeMirror type) { - return "Implicit" + getTypeId(type) + "Cast"; - } - - public static TypeMirror type(TypeSystemData typeSystem, TypeMirror type) { - String typeSystemName = TypeSystemCodeGenerator.typeName(typeSystem); - return new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()) + "." + typeSystemName, typeName(type)); - } - - public static CodeTree create(TypeSystemData typeSystem, TypeMirror type, CodeTree value) { - return CodeTreeBuilder.createBuilder().startStaticCall(type(typeSystem, type), "create").tree(value).end().build(); - } - - public static CodeTree cast(String nodeName, CodeTree value) { - return CodeTreeBuilder.createBuilder().startCall(nodeName, "cast").tree(value).end().build(); - } - - public static CodeTree check(String nodeName, CodeTree value) { - return CodeTreeBuilder.createBuilder().startCall(nodeName, "check").tree(value).end().build(); - } - - private static String seenFieldName(TypeMirror type) { - return "seen" + getTypeId(type); - } - - public CodeTypeElement create() { - String typeName = typeName(forType); - TypeMirror baseType = context.getType(Object.class); - CodeTypeElement clazz = GeneratorUtils.createClass(typeSystem, null, modifiers(PUBLIC, FINAL, STATIC), typeName, baseType); - - for (TypeMirror sourceType : sourceTypes) { - CodeVariableElement hasSeen = new CodeVariableElement(modifiers(PUBLIC), context.getType(boolean.class), seenFieldName(sourceType)); - hasSeen.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(CompilationFinal.class))); - clazz.add(hasSeen); - } - - clazz.add(createConstructor(clazz)); - if (isTypeBoxingOptimized(options.monomorphicTypeBoxingOptimization(), forType)) { - clazz.add(createIsMonomorphic()); - } - clazz.add(createCast(false)); - clazz.add(createCast(true)); - clazz.add(createCheck()); - clazz.add(createMerge(clazz)); - clazz.add(createCreate(clazz)); - - return clazz; - } - - private Element createIsMonomorphic() { - String methodName = "isMonomorphic"; - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), methodName); - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn(); - String operator = ""; - for (TypeMirror sourceType : sourceTypes) { - builder.string(operator); - builder.string(seenFieldName(sourceType)); - operator = " ^ "; - } - builder.end(); - return method; - } - - private static Element createConstructor(CodeTypeElement clazz) { - return new CodeExecutableElement(modifiers(PRIVATE), null, clazz.getSimpleName().toString()); - } - - private Element createCreate(CodeTypeElement clazz) { - String methodName = "create"; - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), clazz.asType(), methodName); - method.addParameter(new CodeVariableElement(context.getType(Object.class), "value")); - CodeTreeBuilder builder = method.createBuilder(); - - builder.declaration(clazz.asType(), "newCast", builder.create().startNew(clazz.asType()).end()); - - for (TypeMirror sourceType : sourceTypes) { - String seenField = seenFieldName(sourceType); - builder.startStatement(); - builder.string("newCast.").string(seenField).string(" = ").tree(TypeSystemCodeGenerator.check(typeSystem, sourceType, "value")); - builder.end(); - } - builder.startReturn().string("newCast").end(); - return method; - } - - private Element createMerge(CodeTypeElement clazz) { - String methodName = "merge"; - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(void.class), methodName); - method.addParameter(new CodeVariableElement(clazz.asType(), "otherCast")); - CodeTreeBuilder builder = method.createBuilder(); - - for (TypeMirror sourceType : sourceTypes) { - String seenField = seenFieldName(sourceType); - builder.startStatement(); - builder.string("this.").string(seenField).string(" |= ").string("otherCast.").string(seenField); - builder.end(); - } - return method; - } - - private Element createCheck() { - String methodName = "check"; - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), methodName); - method.addParameter(new CodeVariableElement(context.getType(Object.class), "value")); - CodeTreeBuilder builder = method.createBuilder(); - - boolean elseIf = false; - for (TypeMirror sourceType : sourceTypes) { - elseIf = builder.startIf(elseIf); - builder.string(seenFieldName(sourceType)).string(" && ").tree(TypeSystemCodeGenerator.check(typeSystem, sourceType, "value")); - builder.end(); - builder.startBlock().returnTrue().end(); - } - builder.returnFalse(); - return method; - } - - private Element createCast(boolean expect) { - String methodName = expect ? "expect" : "cast"; - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), forType, methodName); - method.addParameter(new CodeVariableElement(context.getType(Object.class), "value")); - if (expect) { - method.getThrownTypes().add(context.getType(UnexpectedResultException.class)); - } - - CodeTreeBuilder builder = method.createBuilder(); - - boolean elseIf = false; - for (TypeMirror sourceType : sourceTypes) { - elseIf = builder.startIf(elseIf); - builder.string(seenFieldName(sourceType)).string(" && ").tree(TypeSystemCodeGenerator.check(typeSystem, sourceType, "value")); - builder.end(); - builder.startBlock(); - builder.startReturn(); - CodeTree castTree = TypeSystemCodeGenerator.cast(typeSystem, sourceType, "value"); - ImplicitCastData cast = typeSystem.lookupCast(sourceType, forType); - if (cast != null) { - builder.tree(TypeSystemCodeGenerator.invokeImplicitCast(typeSystem, cast, castTree)); - } else { - builder.tree(castTree); - } - builder.end(); - builder.end(); - } - if (expect) { - builder.startThrow().startNew(context.getType(UnexpectedResultException.class)).string("value").end().end(); - } else { - builder.startStatement().startStaticCall(context.getType(CompilerDirectives.class), "transferToInterpreter").end().end(); - builder.startThrow().startNew(context.getType(AssertionError.class)).end().end(); - } - return method; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2012, 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.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class NodeCodeGenerator extends CodeTypeElementFactory { - - @Override - public CodeTypeElement create(ProcessorContext context, NodeData node) { - List enclosedTypes = new ArrayList<>(); - for (NodeData childNode : node.getEnclosingNodes()) { - CodeTypeElement type = create(context, childNode); - if (type != null) { - enclosedTypes.add(type); - } - } - List generatedNodes = generateNodes(context, node); - - if (!generatedNodes.isEmpty() || !enclosedTypes.isEmpty()) { - CodeTypeElement type; - if (generatedNodes.isEmpty()) { - type = createContainer(node); - } else { - type = wrapGeneratedNodes(context, node, generatedNodes); - } - - for (CodeTypeElement enclosedFactory : enclosedTypes) { - type.add(makeInnerClass(enclosedFactory)); - } - - if (node.getDeclaringNode() == null && enclosedTypes.size() > 0) { - ExecutableElement getFactories = createGetFactories(context, node); - if (getFactories != null) { - type.add(getFactories); - } - } - - return type; - } else { - return null; - } - } - - private static CodeTypeElement makeInnerClass(CodeTypeElement type) { - Set modifiers = type.getModifiers(); - modifiers.add(Modifier.STATIC); - return type; - } - - private static CodeTypeElement wrapGeneratedNodes(ProcessorContext context, NodeData node, List generatedNodes) { - if (node.isGenerateFactory()) { - // wrap all types into a generated factory - CodeTypeElement factoryElement = new NodeFactoryFactory(context, node, generatedNodes.get(0)).create(); - for (CodeTypeElement generatedNode : generatedNodes) { - factoryElement.add(makeInnerClass(generatedNode)); - } - return factoryElement; - } else { - // wrap all types into the first node - CodeTypeElement first = generatedNodes.get(0); - CodeTypeElement second = first; - if (generatedNodes.size() > 1) { - second = generatedNodes.get(1); - for (CodeTypeElement generatedNode : generatedNodes) { - if (first != generatedNode) { - first.add(makeInnerClass(generatedNode)); - } - } - } - new NodeFactoryFactory(context, node, second).createFactoryMethods(first); - ElementUtils.setVisibility(first.getModifiers(), ElementUtils.getVisibility(node.getTemplateType().getModifiers())); - - return first; - } - } - - private static CodeTypeElement createContainer(NodeData node) { - CodeTypeElement container; - Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers()); - String containerName = NodeFactoryFactory.factoryClassName(node); - container = GeneratorUtils.createClass(node, null, modifiers(), containerName, null); - if (visibility != null) { - container.getModifiers().add(visibility); - } - container.getModifiers().add(Modifier.FINAL); - - return container; - } - - private static String getAccessorClassName(NodeData node) { - return node.isGenerateFactory() ? NodeFactoryFactory.factoryClassName(node) : NodeGenFactory.nodeTypeName(node); - } - - private static List generateNodes(ProcessorContext context, NodeData node) { - if (!node.needsFactory()) { - return Collections.emptyList(); - } - return Arrays.asList(new NodeGenFactory(context, node).create()); - } - - private static ExecutableElement createGetFactories(ProcessorContext context, NodeData node) { - List factoryList = node.getNodesWithFactories(); - if (node.needsFactory() && node.isGenerateFactory()) { - factoryList.add(node); - } - - if (factoryList.isEmpty()) { - return null; - } - - List nodeTypesList = new ArrayList<>(); - TypeMirror prev = null; - boolean allSame = true; - for (NodeData child : factoryList) { - nodeTypesList.add(child.getNodeType()); - if (prev != null && !ElementUtils.typeEquals(child.getNodeType(), prev)) { - allSame = false; - } - prev = child.getNodeType(); - } - TypeMirror commonNodeSuperType = ElementUtils.getCommonSuperType(context, nodeTypesList); - - Types types = context.getEnvironment().getTypeUtils(); - TypeMirror factoryType = context.getType(NodeFactory.class); - TypeMirror baseType; - if (allSame) { - baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), commonNodeSuperType); - } else { - baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null)); - } - TypeMirror listType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(List.class)), baseType); - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories"); - - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn(); - - if (factoryList.size() > 1) { - builder.startStaticCall(context.getType(Arrays.class), "asList"); - } else { - builder.startStaticCall(context.getType(Collections.class), "singletonList"); - } - - for (NodeData child : factoryList) { - builder.startGroup(); - NodeData childNode = child; - List factories = new ArrayList<>(); - while (childNode.getDeclaringNode() != null) { - factories.add(childNode); - childNode = childNode.getDeclaringNode(); - } - Collections.reverse(factories); - for (NodeData nodeData : factories) { - - builder.string(getAccessorClassName(nodeData)).string("."); - } - builder.string("getInstance()"); - builder.end(); - } - builder.end(); - builder.end(); - - return method; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeFactoryFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeFactoryFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +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.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; -import com.oracle.truffle.dsl.processor.model.*; - -class NodeFactoryFactory { - - static final String EMPTY_CLASS_ARRAY = "EMPTY_CLASS_ARRAY"; - - private final ProcessorContext context; - private final NodeData node; - private final CodeTypeElement createdFactoryElement; - - public NodeFactoryFactory(ProcessorContext context, NodeData node, CodeTypeElement createdClass) { - this.context = context; - this.node = node; - this.createdFactoryElement = createdClass; - } - - public static String factoryClassName(NodeData node) { - return node.getNodeId() + "Factory"; - } - - public CodeTypeElement create() { - Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers()); - TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getTruffleTypes().getNodeFactoryBase()), node.getNodeType()); - - CodeTypeElement clazz = GeneratorUtils.createClass(node, null, modifiers(), factoryClassName(node), null); - if (visibility != null) { - clazz.getModifiers().add(visibility); - } - clazz.getModifiers().add(Modifier.FINAL); - - if (createdFactoryElement != null) { - clazz.setSuperClass(nodeFactory); - clazz.add(createNodeFactoryConstructor()); - clazz.add(createCreateNodeMethod()); - clazz.add(createGetInstanceMethod(visibility)); - clazz.add(createInstanceConstant(clazz.asType())); - createFactoryMethods(clazz); - } - - return clazz; - } - - private Element createNodeFactoryConstructor() { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), null, factoryClassName(node)); - CodeTreeBuilder builder = method.createBuilder(); - builder.startStatement(); - builder.startCall("super"); - - // node type - builder.typeLiteral(node.getNodeType()); - - // execution signature - builder.startGroup(); - if (node.getChildExecutions().isEmpty()) { - builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); - } else { - builder.startNewArray(new ArrayCodeTypeMirror(context.getType(Class.class)), null); - for (NodeExecutionData execution : node.getChildExecutions()) { - builder.typeLiteral(execution.getNodeType()); - } - builder.end(); - } - builder.end(); - - // node signatures - builder.startGroup(); - builder.startNewArray(new ArrayCodeTypeMirror(new ArrayCodeTypeMirror(context.getType(Class.class))), null); - List constructors = GeneratorUtils.findUserConstructors(createdFactoryElement.asType()); - for (ExecutableElement constructor : constructors) { - builder.startGroup(); - if (constructor.getParameters().isEmpty()) { - builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); - } else { - builder.startNewArray(new ArrayCodeTypeMirror(context.getType(Class.class)), null); - for (VariableElement var : constructor.getParameters()) { - builder.typeLiteral(var.asType()); - } - builder.end(); - } - builder.end(); - } - builder.end(); - builder.end(); - - builder.end().end().end(); - return method; - } - - private CodeExecutableElement createCreateNodeMethod() { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode"); - CodeVariableElement arguments = new CodeVariableElement(context.getType(Object.class), "arguments"); - method.setVarArgs(true); - method.addParameter(arguments); - - CodeTreeBuilder builder = method.createBuilder(); - List signatures = GeneratorUtils.findUserConstructors(createdFactoryElement.asType()); - boolean ifStarted = false; - - for (ExecutableElement element : signatures) { - ifStarted = builder.startIf(ifStarted); - builder.string("arguments.length == " + element.getParameters().size()); - - int index = 0; - for (VariableElement param : element.getParameters()) { - if (ElementUtils.isObject(param.asType())) { - continue; - } - builder.string(" && "); - if (!param.asType().getKind().isPrimitive()) { - builder.string("(arguments[" + index + "] == null || "); - } - builder.string("arguments[" + index + "] instanceof "); - builder.type(ElementUtils.boxType(context, param.asType())); - if (!param.asType().getKind().isPrimitive()) { - builder.string(")"); - } - index++; - } - builder.end(); - builder.startBlock(); - - builder.startReturn().startCall("create"); - index = 0; - for (VariableElement param : element.getParameters()) { - builder.startGroup(); - if (!ElementUtils.isObject(param.asType())) { - builder.string("(").type(param.asType()).string(") "); - } - builder.string("arguments[").string(String.valueOf(index)).string("]"); - builder.end(); - index++; - } - builder.end().end(); - - builder.end(); // block - } - - builder.startElseBlock(); - builder.startThrow().startNew(context.getType(IllegalArgumentException.class)); - builder.doubleQuote("Invalid create signature."); - builder.end().end(); - builder.end(); // else block - return method; - } - - private ExecutableElement createGetInstanceMethod(Modifier visibility) { - TypeElement nodeFactoryType = ElementUtils.fromTypeMirror(context.getType(NodeFactory.class)); - TypeMirror returnType = ElementUtils.getDeclaredType(nodeFactoryType, node.getNodeType()); - - CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance"); - if (visibility != null) { - method.getModifiers().add(visibility); - } - method.getModifiers().add(Modifier.STATIC); - - String varName = instanceVarName(node); - - CodeTreeBuilder builder = method.createBuilder(); - builder.startIf(); - builder.string(varName).string(" == null"); - builder.end().startBlock(); - - builder.startStatement(); - builder.string(varName); - builder.string(" = "); - builder.startNew(factoryClassName(node)).end(); - builder.end(); - - builder.end(); - builder.startReturn().string(varName).end(); - return method; - } - - private static String instanceVarName(NodeData node) { - if (node.getDeclaringNode() != null) { - return ElementUtils.firstLetterLowerCase(factoryClassName(node)) + "Instance"; - } else { - return "instance"; - } - } - - private CodeVariableElement createInstanceConstant(TypeMirror factoryType) { - String varName = instanceVarName(node); - CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName); - var.getModifiers().add(Modifier.PRIVATE); - var.getModifiers().add(Modifier.STATIC); - return var; - } - - public void createFactoryMethods(CodeTypeElement clazz) { - List constructors = GeneratorUtils.findUserConstructors(createdFactoryElement.asType()); - for (ExecutableElement constructor : constructors) { - clazz.add(createCreateMethod(constructor)); - if (constructor instanceof CodeExecutableElement) { - ElementUtils.setVisibility(constructor.getModifiers(), Modifier.PRIVATE); - } - } - } - - private CodeExecutableElement createCreateMethod(ExecutableElement constructor) { - CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), constructor); - method.setSimpleName(CodeNames.of("create")); - method.getModifiers().clear(); - method.getModifiers().add(Modifier.PUBLIC); - method.getModifiers().add(Modifier.STATIC); - method.setReturnType(node.getNodeType()); - - CodeTreeBuilder body = method.createBuilder(); - body.startReturn(); - if (node.getSpecializations().isEmpty()) { - body.nullLiteral(); - } else { - body.startNew(NodeGenFactory.nodeType(node)); - for (VariableElement var : method.getParameters()) { - body.string(var.getSimpleName().toString()); - } - body.end(); - - } - body.end(); - return method; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3044 +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.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.generator.GeneratorUtils.*; -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.dsl.internal.DSLOptions.ImplicitCastOptimization; -import com.oracle.truffle.api.dsl.internal.DSLOptions.TypeBoxingOptimization; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.parser.*; -import com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard; - -public class NodeGenFactory { - - private static final String FRAME_VALUE = TemplateMethod.FRAME_NAME; - private static final String NAME_SUFFIX = "_"; - private static final String NODE_SUFFIX = "NodeGen"; - - private final ProcessorContext context; - private final NodeData node; - private final TypeSystemData typeSystem; - private final TypeMirror genericType; - private final DSLOptions options; - private final boolean singleSpecializable; - private final int varArgsThreshold; - private final Set expectedTypes = new HashSet<>(); - private final Set usedExecuteChildMethods = new HashSet<>(); - private boolean nextUsed; - private boolean singleSpecializableUnsupportedUsed; - - private List usedTypes; - private List reachableSpecializations; - - public NodeGenFactory(ProcessorContext context, NodeData node) { - this.context = context; - this.node = node; - this.typeSystem = node.getTypeSystem(); - this.genericType = context.getType(Object.class); - this.options = typeSystem.getOptions(); - this.varArgsThreshold = calculateVarArgsThreshold(); - this.reachableSpecializations = calculateReachableSpecializations(); - this.singleSpecializable = isSingleSpecializableImpl(); - this.usedTypes = filterBaseExecutableTypes(node.getExecutableTypes(), reachableSpecializations); - } - - private int calculateVarArgsThreshold() { - TypeMirror specialization = context.getType(SpecializationNode.class); - TypeElement specializationType = fromTypeMirror(specialization); - - int maxParameters = 0; - for (ExecutableElement element : ElementFilter.methodsIn(specializationType.getEnclosedElements())) { - if (element.getSimpleName().contentEquals("acceptAndExecute")) { - maxParameters = Math.max(maxParameters, element.getParameters().size()); - } - } - return maxParameters; - } - - public static String nodeTypeName(NodeData node) { - return resolveNodeId(node) + NODE_SUFFIX; - } - - private static String assumptionName(AssumptionExpression assumption) { - return assumption.getId() + NAME_SUFFIX; - } - - private static String resolveNodeId(NodeData node) { - String nodeid = node.getNodeId(); - if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { - nodeid = nodeid.substring(0, nodeid.length() - 4); - } - return nodeid; - } - - public static TypeMirror nodeType(NodeData node) { - return new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), nodeTypeName(node)); - } - - private static String specializationTypeName(SpecializationData specialization) { - String id; - if (specialization == null) { - id = "Base"; - } else { - id = specialization.getId(); - } - return id + "Node_"; - } - - private TypeMirror specializationType(SpecializationData specialization) { - return new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()) + "." + nodeTypeName(node), specializationTypeName(specialization)); - } - - private static String polymorphicTypeProfileFieldName(NodeExecutionData execution) { - return execution.getName() + "Type" + NAME_SUFFIX; - } - - private static String nodeFieldName(NodeExecutionData execution) { - return execution.getName() + NAME_SUFFIX; - } - - private static String specializationStartFieldName() { - return "specialization" + NAME_SUFFIX; - } - - private static String excludedFieldName(SpecializationData specialization) { - return "exclude" + specialization.getId() + NAME_SUFFIX; - } - - private static String executeChildMethodName(NodeExecutionData execution, TypeMirror type) { - return "execute" + ElementUtils.firstLetterUpperCase(execution.getName()) + (ElementUtils.isObject(type) ? "" : getTypeId(type)) + NAME_SUFFIX; - } - - private CodeTree accessParent(String name) { - if (singleSpecializable) { - if (name == null) { - return CodeTreeBuilder.singleString("this"); - } else { - return CodeTreeBuilder.singleString(name); - } - } else { - if (name == null) { - return CodeTreeBuilder.singleString("root"); - } else { - return CodeTreeBuilder.createBuilder().string("root.").string(name).build(); - } - } - } - - public CodeTypeElement create() { - CodeTypeElement clazz = GeneratorUtils.createClass(node, null, modifiers(FINAL), nodeTypeName(node), node.getTemplateType().asType()); - ElementUtils.setVisibility(clazz.getModifiers(), ElementUtils.getVisibility(node.getTemplateType().getModifiers())); - - for (NodeChildData child : node.getChildren()) { - clazz.addOptional(createAccessChildMethod(child)); - } - - for (NodeFieldData field : node.getFields()) { - if (!field.isGenerated()) { - continue; - } - - clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), field.getType(), field.getName())); - if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { - CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter()); - method.getModifiers().remove(Modifier.ABSTRACT); - method.createBuilder().startReturn().string("this.").string(field.getName()).end(); - clazz.add(method); - } - } - - for (ExecutableElement superConstructor : GeneratorUtils.findUserConstructors(node.getTemplateType().asType())) { - clazz.add(createNodeConstructor(clazz, superConstructor)); - } - - for (NodeExecutionData execution : node.getChildExecutions()) { - if (execution.getChild() != null) { - clazz.add(createNodeField(PRIVATE, execution.getNodeType(), nodeFieldName(execution), Child.class)); - } - } - - for (NodeExecutionData execution : node.getChildExecutions()) { - if (!resolvePolymorphicExecutables(execution).isEmpty()) { - clazz.add(createNodeField(PRIVATE, getType(Class.class), polymorphicTypeProfileFieldName(execution), CompilationFinal.class)); - } - } - - for (SpecializationData specialization : node.getSpecializations()) { - if (mayBeExcluded(specialization)) { - clazz.add(createNodeField(PRIVATE, getType(boolean.class), excludedFieldName(specialization), CompilationFinal.class)); - } - } - - clazz.add(createGetCostMethod()); - - avoidFindbugsProblems(clazz); - - if (singleSpecializable) { - SpecializationData specialization = reachableSpecializations.iterator().next(); - - for (ExecutableTypeData execType : usedTypes) { - if (execType.getMethod() == null) { - boolean foundDelegate = false; - for (ExecutableTypeData type : usedTypes) { - if (type == execType) { - continue; - } - if (findFastPathDelegate(specialization.getReturnType().getType(), type, usedTypes) == execType) { - foundDelegate = true; - break; - } - } - // just exclude synthetic execute methods that were not delegated to - if (!foundDelegate) { - continue; - } - } - - clazz.add(createExecutableTypeOverride(usedTypes, execType)); - } - - if (singleSpecializableUnsupportedUsed) { - addUnsupportedMethod(clazz); - } - } else { - - for (ExecutableTypeData execType : usedTypes) { - if (execType.getMethod() == null) { - continue; - } - clazz.add(createExecutableTypeOverride(usedTypes, execType)); - } - - clazz.getImplements().add(getType(SpecializedNode.class)); - clazz.add(createMethodGetSpecializationNode()); - clazz.add(createDeepCopyMethod()); - SpecializationData specializationStart = createSpecializations(clazz); - clazz.add(createNodeField(PRIVATE, specializationType(null), specializationStartFieldName(), Child.class)); - - for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) { - CodeTreeBuilder builder = ((CodeExecutableElement) constructor).appendBuilder(); - builder.startStatement(); - builder.string("this.").string(specializationStartFieldName()); - builder.string(" = ").tree(createCallCreateMethod(specializationStart, "this", null)); - builder.end(); - } - } - - for (TypeMirror type : ElementUtils.uniqueSortedTypes(expectedTypes, false)) { - if (!typeSystem.hasType(type)) { - clazz.addOptional(TypeSystemCodeGenerator.createExpectMethod(PRIVATE, typeSystem, context.getType(Object.class), type)); - } - } - - return clazz; - } - - private void avoidFindbugsProblems(CodeTypeElement clazz) { - TypeElement type = context.getEnvironment().getElementUtils().getTypeElement("edu.umd.cs.findbugs.annotations.SuppressFBWarnings"); - if (type == null) { - return; - } - boolean foundComparison = false; - outer: for (SpecializationData specialization : node.getSpecializations()) { - for (GuardExpression guard : specialization.getGuards()) { - if (guard.getExpression().containsComparisons()) { - foundComparison = true; - break outer; - } - } - } - - if (foundComparison) { - CodeAnnotationMirror annotation = new CodeAnnotationMirror((DeclaredType) type.asType()); - annotation.setElementValue(annotation.findExecutableElement("value"), new CodeAnnotationValue("SA_LOCAL_SELF_COMPARISON")); - clazz.addAnnotationMirror(annotation); - } - } - - private void addUnsupportedMethod(CodeTypeElement clazz) { - CodeVariableElement seenUnsupportedField = new CodeVariableElement(modifiers(PRIVATE), getType(boolean.class), "seenUnsupported0"); - seenUnsupportedField.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(CompilationFinal.class))); - clazz.add(seenUnsupportedField); - LocalContext locals = LocalContext.load(this); - CodeExecutableElement method = locals.createMethod(modifiers(PRIVATE), getType(UnsupportedSpecializationException.class), "unsupported", varArgsThreshold); - CodeTreeBuilder builder = method.createBuilder(); - builder.startIf().string("!").string(seenUnsupportedField.getName()).end().startBlock(); - builder.startStatement().startStaticCall(getType(CompilerDirectives.class), "transferToInterpreterAndInvalidate").end().end(); - builder.startStatement().string(seenUnsupportedField.getName()).string(" = true").end(); - builder.end(); - - builder.startReturn(); - builder.startNew(getType(UnsupportedSpecializationException.class)); - builder.string("this"); - builder.tree(createGetSuppliedChildren()); - locals.addReferencesTo(builder); - builder.end(); - builder.end(); - clazz.add(method); - } - - private CodeExecutableElement createNodeConstructor(CodeTypeElement clazz, ExecutableElement superConstructor) { - CodeExecutableElement constructor = GeneratorUtils.createConstructorUsingFields(modifiers(), clazz, superConstructor); - ElementUtils.setVisibility(constructor.getModifiers(), ElementUtils.getVisibility(superConstructor.getModifiers())); - - List childParameters = new ArrayList<>(); - for (NodeChildData child : node.getChildren()) { - childParameters.add(new CodeVariableElement(child.getOriginalType(), child.getName())); - } - constructor.getParameters().addAll(superConstructor.getParameters().size(), childParameters); - - CodeTreeBuilder builder = constructor.appendBuilder(); - List childValues = new ArrayList<>(node.getChildren().size()); - for (NodeChildData child : node.getChildren()) { - String name = child.getName(); - if (child.getCardinality().isMany()) { - CreateCastData createCast = node.findCast(child.getName()); - if (createCast != null) { - CodeTree nameTree = CodeTreeBuilder.singleString(name); - CodeTreeBuilder callBuilder = builder.create(); - callBuilder.string(name).string(" != null ? "); - callBuilder.tree(callMethod(null, createCast.getMethod(), nameTree)); - callBuilder.string(" : null"); - name += "_"; - builder.declaration(child.getNodeType(), name, callBuilder.build()); - } - } - childValues.add(name); - } - - for (NodeExecutionData execution : node.getChildExecutions()) { - if (execution.getChild() == null) { - continue; - } - CreateCastData createCast = node.findCast(execution.getChild().getName()); - - builder.startStatement(); - builder.string("this.").string(nodeFieldName(execution)).string(" = "); - - String name = childValues.get(node.getChildren().indexOf(execution.getChild())); - CodeTreeBuilder accessorBuilder = builder.create(); - accessorBuilder.string(name); - - if (execution.isIndexed()) { - accessorBuilder.string("[").string(String.valueOf(execution.getChildIndex())).string("]"); - } - - CodeTree accessor = accessorBuilder.build(); - - if (createCast != null && execution.getChild().getCardinality().isOne()) { - accessor = callMethod(null, createCast.getMethod(), accessor); - } - - if (execution.isIndexed()) { - CodeTreeBuilder nullCheck = builder.create(); - nullCheck.string(name).string(" != null && ").string(String.valueOf(execution.getChildIndex())).string(" < ").string(name).string(".length").string(" ? "); - nullCheck.tree(accessor); - nullCheck.string(" : null"); - accessor = nullCheck.build(); - } - - builder.tree(accessor); - - builder.end(); - } - - return constructor; - } - - private static boolean mayBeExcluded(SpecializationData specialization) { - return !specialization.getExceptions().isEmpty() || !specialization.getExcludedBy().isEmpty(); - } - - private SpecializationData createSpecializations(CodeTypeElement clazz) { - CodeTypeElement baseSpecialization = clazz.add(createBaseSpecialization()); - TypeMirror baseSpecializationType = baseSpecialization.asType(); - - Map generated = new LinkedHashMap<>(); - - List generateSpecializations = new ArrayList<>(); - generateSpecializations.add(node.getUninitializedSpecialization()); - if (needsPolymorphic()) { - generateSpecializations.add(node.getPolymorphicSpecialization()); - } - generateSpecializations.addAll(reachableSpecializations); - - for (SpecializationData specialization : generateSpecializations) { - generated.put(specialization, clazz.add(createSpecialization(specialization, baseSpecializationType))); - } - - baseSpecialization.addOptional(createCreateNext(generated)); - baseSpecialization.addOptional(createCreateFallback(generated)); - baseSpecialization.addOptional(createCreatePolymorphic(generated)); - baseSpecialization.addOptional(createGetNext(baseSpecialization)); - - for (NodeExecutionData execution : node.getChildExecutions()) { - Collection specializedTypes = node.findSpecializedTypes(execution); - specializedTypes.add(genericType); - for (TypeMirror specializedType : specializedTypes) { - if (isExecuteChildShared(execution, specializedType)) { - baseSpecialization.addOptional(createExecuteChildMethod(execution, specializedType)); - } - } - } - - return node.getUninitializedSpecialization(); - } - - private boolean needsPolymorphic() { - int signatureSize = node.getSignatureSize(); - boolean allEvaluated = true; - for (ExecutableTypeData type : usedTypes) { - if (type.getEvaluatedCount() != signatureSize) { - allEvaluated = false; - } - } - if (allEvaluated) { - return false; - } - - if (reachableSpecializations.size() != 1) { - return true; - } - - SpecializationData specialization = reachableSpecializations.get(0); - for (Parameter parameter : specialization.getSignatureParameters()) { - TypeMirror type = parameter.getType(); - if (type != null && typeSystem.hasImplicitSourceTypes(type)) { - return true; - } - } - if (specialization.hasMultipleInstances()) { - return true; - } - return false; - - } - - // create specialization - - private CodeTypeElement createBaseSpecialization() { - CodeTypeElement clazz = createClass(node, null, modifiers(PRIVATE, ABSTRACT, STATIC), specializationTypeName(null), typeSystem.getContext().getType(SpecializationNode.class)); - - clazz.addOptional(createSpecializationConstructor(clazz, null, null)); - clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), nodeType(node), "root")); - - clazz.addOptional(createUnsupported()); - clazz.add(createGetSuppliedChildrenMethod()); - clazz.add(createAcceptAndExecute()); - - for (ExecutableTypeData type : usedTypes) { - clazz.add(createFastPathExecuteMethod(null, type, usedTypes)); - } - - return clazz; - } - - private Element createAcceptAndExecute() { - ExecutableTypeData executableElement = createSpecializationNodeSignature(node.getSignatureSize()); - LocalContext currentLocals = LocalContext.load(this, executableElement, varArgsThreshold); - CodeExecutableElement executable = createExecuteMethod(null, executableElement, currentLocals, false, varArgsThreshold); - - executable.getModifiers().add(FINAL); - CodeTreeBuilder builder = executable.createBuilder(); - - CodeTree receiver = CodeTreeBuilder.singleString("this"); - - builder.tree(createCallDelegateExecute(builder, receiver, currentLocals, executableElement, node.getGenericExecutableType(null))); - - return executable; - } - - private ExecutableTypeData createSpecializationNodeSignature(int argumentCount) { - TypeMirror[] parameters = new TypeMirror[argumentCount]; - Arrays.fill(parameters, genericType); - return new ExecutableTypeData(node, genericType, "acceptAndExecute", context.getType(Frame.class), Arrays.asList(parameters)); - } - - private boolean shouldImplementExecutableType(SpecializationData specialization, ExecutableTypeData executableType) { - // always implement the root execute method. they are declared abstract in the base node. - if (executableType.getDelegatedTo() == null) { - return true; - } - - // specializations with more parameters are just ignored - if (executableType.getEvaluatedCount() > node.getExecutionCount()) { - return false; - } - - if (!isSubtypeBoxed(context, specialization.getReturnType().getType(), executableType.getReturnType())) { - return false; - } - - // the evaluated signature might be compatible to the specialization - boolean specializationCompatible = true; - List signatureParameters = executableType.getSignatureParameters(); - for (int i = 0; i < signatureParameters.size(); i++) { - TypeMirror evaluatedType = signatureParameters.get(i); - TypeMirror specializedType = specialization.findParameterOrDie(node.getChildExecutions().get(i)).getType(); - - if (!isSubtypeBoxed(context, evaluatedType, specializedType) && !isSubtypeBoxed(context, specializedType, evaluatedType)) { - specializationCompatible = false; - break; - } - } - if (!specializationCompatible) { - return false; - } - - // possibly trigger void optimization for a specialization if it is enabled - if (isVoid(executableType.getReturnType())) { - if (isTypeBoxingOptimized(options.voidBoxingOptimization(), specialization.getReturnType().getType())) { - return true; - } - } - - // trigger type boxing elimination for unevaluated arguments - for (int i = executableType.getEvaluatedCount(); i < node.getExecutionCount(); i++) { - NodeExecutionData execution = node.getChildExecutions().get(i); - TypeMirror specializedType = specialization.findParameterOrDie(execution).getType(); - if (isTypeBoxingOptimized(options.monomorphicTypeBoxingOptimization(), specializedType)) { - // it does not make sense to do type boxing elimination for children with - // no type specialized execute method - if (execution.getChild() != null) { - ExecutableTypeData executedType = execution.getChild().findExecutableType(specializedType); - if (executedType != null) { - return true; - } - } - } - } - - // trigger type boxing elimination for return types - if (typeEquals(executableType.getReturnType(), specialization.getReturnType().getType())) { - if (isTypeBoxingOptimized(options.monomorphicTypeBoxingOptimization(), executableType.getReturnType())) { - return true; - } - } - - // trigger generation for evaluated assignable type matches other than generic - for (int i = 0; i < signatureParameters.size(); i++) { - TypeMirror evaluatedType = signatureParameters.get(i); - NodeExecutionData execution = node.getChildExecutions().get(i); - TypeMirror specializedType = specialization.findParameterOrDie(execution).getType(); - - if (isSubtypeBoxed(context, evaluatedType, specializedType) && !isObject(specializedType)) { - return true; - } - } - - return false; - } - - private List filterBaseExecutableTypes(List executableTypes, List specializations) { - Set returnTypes = new HashSet<>(); - for (SpecializationData specialization : node.getSpecializations()) { - returnTypes.add(specialization.getReturnType().getType()); - } - - List prefilteredTypes = new ArrayList<>(); - for (ExecutableTypeData type : executableTypes) { - if (type.getDelegatedTo() == null || shouldAlwaysImplementExecutableType(type)) { - prefilteredTypes.add(type); - } else { - boolean foundSubtype = false; - for (TypeMirror returnType : returnTypes) { - if (isSubtypeBoxed(context, returnType, type.getReturnType())) { - foundSubtype = true; - } - } - if (foundSubtype) { - prefilteredTypes.add(type); - } - } - } - - Set types = new HashSet<>(); - type: for (ExecutableTypeData type : prefilteredTypes) { - for (SpecializationData specialization : specializations) { - if (shouldImplementExecutableType(specialization, type) || shouldAlwaysImplementExecutableType(type)) { - types.add(type); - continue type; - } - } - } - Set delegatesToAdd = new HashSet<>(); - do { - delegatesToAdd.clear(); - for (ExecutableTypeData type : types) { - ExecutableTypeData delegate = type.getDelegatedTo(); - if (delegate != null && !types.contains(delegate)) { - delegatesToAdd.add(delegate); - } - } - types.addAll(delegatesToAdd); - } while (!delegatesToAdd.isEmpty()); - List newUsedTypes = new ArrayList<>(types); - Collections.sort(newUsedTypes); - return newUsedTypes; - } - - private boolean shouldAlwaysImplementExecutableType(ExecutableTypeData type) { - return type.isAbstract() || !(type.hasUnexpectedValue(context) && type.getMethod() != null); - } - - private CodeTypeElement createSpecialization(SpecializationData specialization, TypeMirror baseType) { - CodeTypeElement clazz = createClass(node, specialization, modifiers(PRIVATE, STATIC, FINAL), specializationTypeName(specialization), baseType); - - CodeExecutableElement constructor = clazz.addOptional(createSpecializationConstructor(clazz, specialization, null)); - - for (Parameter p : specialization.getSignatureParameters()) { - TypeMirror targetType = p.getType(); - if (typeSystem.hasImplicitSourceTypes(targetType)) { - NodeExecutionData execution = p.getSpecification().getExecution(); - CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, p.getType()); - if (implicitProfile != null) { - implicitProfile.getModifiers().add(PRIVATE); - implicitProfile.getModifiers().add(FINAL); - clazz.add(implicitProfile); - } - } - } - - if (specialization.isFallback()) { - clazz.add(createFallbackGuardMethod()); - } - - clazz.addOptional(createSpecializationCreateMethod(specialization, constructor)); - clazz.addOptional(createMergeMethod(specialization)); - clazz.addOptional(createIsSameMethod(specialization)); - clazz.addOptional(createIsIdenticalMethod(specialization)); - - // get types that should get implemented - List types = new ArrayList<>(); - for (ExecutableTypeData type : node.getExecutableTypes()) { - if (shouldImplementExecutableType(specialization, type)) { - types.add(type); - } - } - for (ExecutableTypeData type : types) { - clazz.add(createFastPathExecuteMethod(specialization, type, types)); - } - - return clazz; - } - - public static List getDynamicParameters(TemplateMethod method) { - List parameters = new ArrayList<>(); - for (Parameter param : method.getReturnTypeAndParameters()) { - if (param.getSpecification().isLocal()) { - // ignore parameters passed by locals - continue; - } else if (param.getVariableElement() != null && param.getVariableElement().getAnnotation(Cached.class) != null) { - // ignore cached parameters - continue; - } - parameters.add(param); - } - return parameters; - } - - private Element createDeepCopyMethod() { - if (singleSpecializable) { - return null; - } - CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), getType(Node.class), "deepCopy"); - executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - CodeTreeBuilder builder = executable.createBuilder(); - builder.startReturn().startStaticCall(getType(SpecializationNode.class), "updateRoot").string("super.deepCopy()").end().end(); - return executable; - } - - private Element createGetCostMethod() { - TypeMirror returnType = getType(NodeCost.class); - CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getCost"); - executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - CodeTreeBuilder builder = executable.createBuilder(); - if (singleSpecializable) { - builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end().end(); - } else { - builder.startReturn().startCall(specializationStartFieldName(), "getNodeCost").end().end(); - } - return executable; - - } - - private Element createIsIdenticalMethod(SpecializationData specialization) { - boolean cacheBoundGuard = specialization.hasMultipleInstances(); - if (!cacheBoundGuard) { - return null; - } - - LocalContext currentLocals = LocalContext.load(this, createSpecializationNodeSignature(node.getSignatureSize()), varArgsThreshold); - currentLocals.loadFastPathState(specialization); - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isIdentical"); - method.addParameter(new CodeVariableElement(getType(SpecializationNode.class), "other")); - currentLocals.addParametersTo(method, varArgsThreshold, FRAME_VALUE); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - final CodeTreeBuilder builder = method.createBuilder(); - - SpecializationGroup group = SpecializationGroup.create(specialization); - SpecializationBody executionFactory = new SpecializationBody(true, false) { - @Override - public CodeTree createBody(SpecializationData s, LocalContext values) { - return builder.create().returnTrue().build(); - } - }; - - builder.tree(createGuardAndCast(group, genericType, currentLocals, executionFactory)); - builder.returnFalse(); - return method; - } - - private CodeExecutableElement createIsSameMethod(SpecializationData specialization) { - if (!specialization.isSpecialized() || !options.implicitCastOptimization().isDuplicateTail()) { - return null; - } - - List profiles = new ArrayList<>(); - for (Parameter parameter : specialization.getSignatureParameters()) { - NodeExecutionData execution = parameter.getSpecification().getExecution(); - if (execution == null) { - continue; - } - CodeVariableElement var = createImplicitProfileParameter(execution, parameter.getType()); - if (var != null) { - profiles.add(var); - } - } - - if (profiles.isEmpty()) { - return null; - } - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isSame"); - method.addParameter(new CodeVariableElement(getType(SpecializationNode.class), "other")); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - CodeTreeBuilder builder = method.createBuilder(); - - builder.startReturn(); - builder.string("super.isSame(other)"); - - for (CodeVariableElement profile : profiles) { - builder.string(" && "); - builder.string("this.").string(profile.getName()).string(" == ").string("(").cast(specializationType(specialization)).string("other).").string(profile.getName()); - } - - builder.end(); - return method; - } - - private Element createMergeMethod(SpecializationData specialization) { - if (specialization.getExcludedBy().isEmpty() && !specialization.isPolymorphic()) { - return null; - } - TypeMirror specializationNodeType = getType(SpecializationNode.class); - LocalContext currentLocals = LocalContext.load(this, createSpecializationNodeSignature(node.getSignatureSize()), varArgsThreshold); - - CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), specializationNodeType, "merge"); - executable.addParameter(new CodeVariableElement(specializationNodeType, "newNode")); - currentLocals.addParametersTo(executable, varArgsThreshold, FRAME_VALUE); - executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - CodeTreeBuilder builder = executable.createBuilder(); - - if (specialization.isPolymorphic()) { - builder.startReturn(); - builder.startCall("polymorphicMerge"); - builder.string("newNode"); - builder.startCall("super", "merge"); - builder.string("newNode"); - currentLocals.addReferencesTo(builder, FRAME_VALUE); - builder.end(); - builder.end(); - builder.end(); - - } else { - boolean elseIf = false; - for (SpecializationData containedSpecialization : specialization.getExcludedBy()) { - elseIf = builder.startIf(elseIf); - builder.string("newNode.getClass() == ").typeLiteral(specializationType(containedSpecialization)); - builder.end(); - builder.startBlock(); - builder.statement("removeSame(\"Contained by " + containedSpecialization.createReferenceName() + "\")"); - builder.end(); - } - builder.startReturn(); - builder.startCall("super", "merge"); - builder.string("newNode"); - currentLocals.addReferencesTo(builder, FRAME_VALUE); - builder.end(); - builder.end(); - } - - return executable; - } - - private Element createCreateFallback(Map generatedSpecializationClasses) { - SpecializationData fallback = node.getGenericSpecialization(); - if (fallback == null) { - return null; - } - CodeTypeElement generatedType = generatedSpecializationClasses.get(fallback); - if (generatedType == null) { - return null; - } - - TypeMirror returnType = getType(SpecializationNode.class); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), returnType, "createFallback"); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - method.createBuilder().startReturn().tree(createCallCreateMethod(fallback, null, null)).end(); - return method; - } - - private Element createCreatePolymorphic(Map generatedSpecializationClasses) { - SpecializationData polymorphic = node.getPolymorphicSpecialization(); - CodeTypeElement generatedPolymorphic = generatedSpecializationClasses.get(polymorphic); - if (generatedPolymorphic == null) { - return null; - } - TypeMirror returnType = getType(SpecializationNode.class); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), returnType, "createPolymorphic"); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - method.createBuilder().startReturn().tree(createCallCreateMethod(polymorphic, null, null)).end(); - return method; - } - - private CodeExecutableElement createCreateNext(final Map specializationClasses) { - final LocalContext locals = LocalContext.load(this); - - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), getType(SpecializationNode.class), "createNext", varArgsThreshold, FRAME_VALUE); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - - CodeTreeBuilder builder = method.createBuilder(); - SpecializationGroup group = createSpecializationGroups(); - CodeTree execution = createGuardAndCast(group, genericType, locals, new SpecializationBody(false, false) { - @Override - public CodeTree createBody(SpecializationData specialization, LocalContext values) { - CodeTypeElement generatedType = specializationClasses.get(specialization); - if (generatedType == null) { - throw new AssertionError("No generated type for " + specialization); - } - return createSlowPathExecute(specialization, values); - } - }); - - builder.tree(execution); - - if (hasFallthrough(group, genericType, locals, false, null)) { - builder.returnNull(); - } - return method; - } - - private CodeExecutableElement createFallbackGuardMethod() { - boolean frameUsed = node.isFrameUsedByAnyGuard(); - LocalContext locals = LocalContext.load(this); - - if (!frameUsed) { - locals.removeValue(FRAME_VALUE); - } - - CodeExecutableElement boundaryMethod = locals.createMethod(modifiers(PRIVATE), getType(boolean.class), "guardFallback", varArgsThreshold, FRAME_VALUE); - if (!frameUsed) { - boundaryMethod.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(TruffleBoundary.class))); - } - - CodeTreeBuilder builder = boundaryMethod.createBuilder(); - builder.startReturn(); - builder.startCall("createNext"); - locals.addReferencesTo(builder, FRAME_VALUE); - builder.end(); - builder.string(" == null"); - builder.end(); - return boundaryMethod; - } - - private ExecutableElement createAccessChildMethod(NodeChildData child) { - if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { - ExecutableElement getter = (ExecutableElement) child.getAccessElement(); - CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), getter); - method.getModifiers().remove(Modifier.ABSTRACT); - - List executions = new ArrayList<>(); - for (NodeExecutionData execution : node.getChildExecutions()) { - if (execution.getChild() == child) { - executions.add(execution); - } - } - - CodeTreeBuilder builder = method.createBuilder(); - if (child.getCardinality().isMany()) { - builder.startReturn().startNewArray((ArrayType) child.getOriginalType(), null); - for (NodeExecutionData execution : executions) { - builder.string(nodeFieldName(execution)); - } - builder.end().end(); - } else { - for (NodeExecutionData execution : executions) { - builder.startReturn().string("this.").string(nodeFieldName(execution)).end(); - break; - } - } - return method; - } - return null; - } - - private Element createUnsupported() { - SpecializationData fallback = node.getGenericSpecialization(); - if (fallback == null || optimizeFallback(fallback) || fallback.getMethod() == null) { - return null; - } - LocalContext locals = LocalContext.load(this); - - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), genericType, "unsupported", varArgsThreshold, FRAME_VALUE); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn(); - builder.tree(callTemplateMethod(accessParent(null), fallback, locals)); - builder.end(); - - return method; - } - - private boolean isSingleSpecializableImpl() { - if (reachableSpecializations.size() != 1) { - return false; - } - - SpecializationData specialization = reachableSpecializations.get(0); - - for (Parameter parameter : specialization.getSignatureParameters()) { - TypeMirror type = parameter.getType(); - if (type != null && typeSystem.hasImplicitSourceTypes(type)) { - return false; - } - } - - if (!specialization.getAssumptionExpressions().isEmpty()) { - return false; - } - - if (specialization.getCaches().size() > 0) { - // TODO chumer: caches do not yet support single specialization. - // it could be worthwhile to explore if this is possible - return false; - } - return true; - } - - private List calculateReachableSpecializations() { - List specializations = new ArrayList<>(); - for (SpecializationData specialization : node.getSpecializations()) { - if (specialization.isReachable() && // - (specialization.isSpecialized() // - || (specialization.isFallback() && optimizeFallback(specialization)))) { - specializations.add(specialization); - } - } - return specializations; - } - - private boolean optimizeFallback(SpecializationData specialization) { - switch (options.optimizeFallback()) { - case NEVER: - return false; - case DECLARED: - return specialization.getMethod() != null; - case ALWAYS: - return true; - default: - throw new AssertionError(); - } - } - - private CodeExecutableElement createExecutableTypeOverride(List usedExecutables, ExecutableTypeData execType) { - LocalContext locals = LocalContext.load(this, execType, Integer.MAX_VALUE); - CodeExecutableElement method = createExecuteMethod(null, execType, locals, true, Integer.MAX_VALUE); - - CodeTreeBuilder builder = method.createBuilder(); - if (singleSpecializable) { - SpecializationData specialization = reachableSpecializations.iterator().next(); - builder.tree(createFastPath(builder, specialization, execType, usedExecutables, locals)); - } else { - // create acceptAndExecute - ExecutableTypeData delegate = execType; - CodeTree receiver = CodeTreeBuilder.singleString(specializationStartFieldName()); - builder.tree(createCallDelegateExecute(builder, receiver, locals, execType, delegate)); - } - return method; - } - - private Element createMethodGetSpecializationNode() { - TypeMirror returntype = getType(SpecializationNode.class); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returntype, "getSpecializationNode"); - method.createBuilder().startReturn().string(specializationStartFieldName()).end(); - return method; - } - - private TypeMirror getType(Class clazz) { - return context.getType(clazz); - } - - private CodeVariableElement createNodeField(Modifier visibility, TypeMirror type, String name, Class annotationType) { - CodeVariableElement childField = new CodeVariableElement(modifiers(), type, name); - childField.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(annotationType))); - setVisibility(childField.getModifiers(), visibility); - return childField; - } - - private static List resolveSpecializedExecutables(NodeExecutionData execution, Collection types, TypeBoxingOptimization optimization) { - if (optimization == TypeBoxingOptimization.NONE) { - return Collections.emptyList(); - } else if (types.isEmpty()) { - return Collections.emptyList(); - } - - List executables = new ArrayList<>(); - for (TypeMirror type : types) { - if (!isTypeBoxingOptimized(optimization, type)) { - continue; - } - if (execution.getChild() == null) { - continue; - } - ExecutableTypeData foundType = execution.getChild().getNodeData().findExecutableType(type, execution.getChild().getExecuteWith().size()); - if (foundType != null) { - executables.add(foundType); - } - } - return executables; - } - - private static CodeTree callMethod(CodeTree receiver, ExecutableElement method, CodeTree... boundValues) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - if (method.getModifiers().contains(STATIC)) { - builder.startStaticCall(method.getEnclosingElement().asType(), method.getSimpleName().toString()); - } else { - builder.startCall(receiver, method.getSimpleName().toString()); - } - int index = -1; - for (VariableElement parameter : method.getParameters()) { - index++; - if (index < boundValues.length) { - CodeTree tree = boundValues[index]; - if (tree != null) { - builder.tree(tree); - continue; - } - } - - builder.defaultValue(parameter.asType()); - } - builder.end(); - return builder.build(); - } - - private CodeTree[] bindExecuteMethodParameters(NodeExecutionData execution, ExecutableTypeData method, LocalContext currentValues) { - List executeWith = execution != null ? execution.getChild().getExecuteWith() : null; - - List values = new ArrayList<>(); - if (method.getFrameParameter() != null) { - LocalVariable frameLocal = currentValues.get(FRAME_VALUE); - if (frameLocal == null) { - values.add(CodeTreeBuilder.singleString("null")); - } else { - values.add(createTypeSafeReference(frameLocal, method.getFrameParameter())); - } - } - - int evaluatedIndex = 0; - for (int executionIndex = 0; executionIndex < node.getExecutionCount(); executionIndex++) { - NodeExecutionData parameterExecution; - if (executeWith != null && executionIndex < executeWith.size()) { - parameterExecution = executeWith.get(executionIndex); - } else { - parameterExecution = node.getChildExecutions().get(executionIndex); - } - if (parameterExecution.isShortCircuit()) { - if (evaluatedIndex < method.getEvaluatedCount()) { - TypeMirror targetType = method.getEvaluatedParameters().get(evaluatedIndex); - LocalVariable shortCircuit = currentValues.getShortCircuit(parameterExecution); - if (shortCircuit != null) { - values.add(createTypeSafeReference(shortCircuit, targetType)); - } else { - values.add(CodeTreeBuilder.createBuilder().defaultValue(targetType).build()); - } - evaluatedIndex++; - } - } - if (evaluatedIndex < method.getEvaluatedCount()) { - TypeMirror targetType = method.getEvaluatedParameters().get(evaluatedIndex); - LocalVariable value = currentValues.getValue(parameterExecution); - if (value != null) { - values.add(createTypeSafeReference(value, targetType)); - } else { - values.add(CodeTreeBuilder.createBuilder().defaultValue(targetType).build()); - } - evaluatedIndex++; - } - } - return values.toArray(new CodeTree[values.size()]); - } - - private CodeTree callExecuteMethod(NodeExecutionData execution, ExecutableTypeData method, LocalContext currentValues) { - CodeTree receiver = execution != null ? accessParent(nodeFieldName(execution)) : null; - return callMethod(receiver, method.getMethod(), bindExecuteMethodParameters(execution, method, currentValues)); - } - - private CodeTree callTemplateMethod(CodeTree receiver, TemplateMethod method, LocalContext currentValues) { - CodeTree[] bindings = new CodeTree[method.getParameters().size()]; - - int signatureIndex = 0; - for (int i = 0; i < bindings.length; i++) { - Parameter parameter = method.getParameters().get(i); - - LocalVariable var = currentValues.get(parameter, signatureIndex); - if (var == null) { - var = currentValues.get(parameter.getLocalName()); - } - - if (var != null) { - bindings[i] = createTypeSafeReference(var, parameter.getType()); - } - - if (parameter.getSpecification().isSignature()) { - signatureIndex++; - } - } - return callMethod(receiver, method.getMethod(), bindings); - } - - private CodeTree createTypeSafeReference(LocalVariable var, TypeMirror targetType) { - CodeTree valueReference = var.createReference(); - TypeMirror sourceType = var.getTypeMirror(); - if (targetType == null || sourceType == null) { - return valueReference; - } - if (needsCastTo(sourceType, targetType)) { - valueReference = TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference); - } - return valueReference; - } - - private SpecializationGroup createSpecializationGroups() { - return SpecializationGroup.create(reachableSpecializations); - } - - private CodeTree createSlowPathExecute(SpecializationData specialization, LocalContext currentValues) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - if (specialization.isFallback()) { - return builder.returnNull().build(); - } - - if (node.isFrameUsedByAnyGuard()) { - builder.tree(createTransferToInterpreterAndInvalidate()); - } - - // caches unbound to guards are invoked after all guards - for (CacheExpression cache : specialization.getCaches()) { - if (!specialization.isCacheBoundByGuard(cache)) { - initializeCache(builder, specialization, cache, currentValues); - } - } - boolean hasAssumptions = !specialization.getAssumptionExpressions().isEmpty(); - if (hasAssumptions) { - - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - CodeTree assumptions = DSLExpressionGenerator.write(assumption.getExpression(), accessParent(null), - castBoundTypes(bindExpressionValues(assumption.getExpression(), specialization, currentValues))); - String name = assumptionName(assumption); - // needs specialization index for assumption to make unique - String varName = name + specialization.getIndex(); - TypeMirror type = assumption.getExpression().getResolvedType(); - builder.declaration(type, varName, assumptions); - currentValues.set(name, new LocalVariable(type, varName, null, null)); - } - - builder.startIf(); - String sep = ""; - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - LocalVariable assumptionVar = currentValues.get(assumptionName(assumption)); - if (assumptionVar == null) { - throw new AssertionError("assumption var not resolved"); - } - builder.string(sep); - builder.startCall("isValid").tree(assumptionVar.createReference()).end(); - sep = " && "; - } - builder.end(); - builder.startBlock(); - } - - for (SpecializationData otherSpeciailzation : node.getSpecializations()) { - if (otherSpeciailzation == specialization) { - continue; - } - if (otherSpeciailzation.getExcludedBy().contains(specialization)) { - builder.startStatement(); - builder.tree(accessParent(excludedFieldName(otherSpeciailzation))); - builder.string(" = true"); - builder.end(); - } - } - - CodeTree create = createCallCreateMethod(specialization, null, currentValues); - - if (specialization.hasMultipleInstances()) { - builder.declaration(getType(SpecializationNode.class), "s", create); - DSLExpression limitExpression = specialization.getLimitExpression(); - CodeTree limitExpressionTree; - if (limitExpression == null) { - limitExpressionTree = CodeTreeBuilder.singleString("3"); - } else { - limitExpressionTree = DSLExpressionGenerator.write(limitExpression, accessParent(null), // - castBoundTypes(bindExpressionValues(limitExpression, specialization, currentValues))); - } - - builder.startIf().string("countSame(s) < ").tree(limitExpressionTree).end().startBlock(); - builder.statement("return s"); - builder.end(); - } else { - builder.startReturn().tree(create).end(); - } - - if (hasAssumptions) { - builder.end(); - } - - if (mayBeExcluded(specialization)) { - CodeTreeBuilder checkHasSeenBuilder = builder.create(); - checkHasSeenBuilder.startIf().string("!").tree(accessParent(excludedFieldName(specialization))).end().startBlock(); - checkHasSeenBuilder.tree(builder.build()); - checkHasSeenBuilder.end(); - return checkHasSeenBuilder.build(); - } - return builder.build(); - } - - private boolean hasFallthrough(SpecializationGroup group, TypeMirror forType, LocalContext currentValues, boolean fastPath, List ignoreGuards) { - for (TypeGuard guard : group.getTypeGuards()) { - if (currentValues.getValue(guard.getSignatureIndex()) == null) { - // not evaluated - return true; - } - LocalVariable value = currentValues.getValue(guard.getSignatureIndex()); - if (needsCastTo(value.getTypeMirror(), guard.getType())) { - return true; - } - } - - List guards = new ArrayList<>(group.getGuards()); - List elseConnectable = group.findElseConnectableGuards(); - guards.removeAll(elseConnectable); - if (ignoreGuards != null) { - guards.removeAll(ignoreGuards); - } - SpecializationData specialization = group.getSpecialization(); - if (specialization != null && fastPath) { - for (ListIterator iterator = guards.listIterator(); iterator.hasNext();) { - GuardExpression guard = iterator.next(); - if (!specialization.isDynamicParameterBound(guard.getExpression())) { - iterator.remove(); - } - } - } - - if (!guards.isEmpty()) { - return true; - } - - if (!fastPath && specialization != null && !specialization.getAssumptionExpressions().isEmpty()) { - return true; - } - - if (!fastPath && specialization != null && mayBeExcluded(specialization)) { - return true; - } - - if (!elseConnectable.isEmpty()) { - SpecializationGroup previous = group.getPrevious(); - if (previous != null && hasFallthrough(previous, forType, currentValues, fastPath, previous.getGuards())) { - return true; - } - } - - List groupChildren = group.getChildren(); - if (!groupChildren.isEmpty()) { - return hasFallthrough(groupChildren.get(groupChildren.size() - 1), forType, currentValues, fastPath, ignoreGuards); - } - - return false; - } - - private Element createGetNext(CodeTypeElement type) { - if (!nextUsed) { - return null; - } - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), type.asType(), "getNext"); - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn().cast(type.asType(), CodeTreeBuilder.singleString("this.next")).end(); - return method; - } - - private Element createGetSuppliedChildrenMethod() { - ArrayType nodeArray = context.getEnvironment().getTypeUtils().getArrayType(getType(Node.class)); - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), nodeArray, "getSuppliedChildren"); - method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn().tree(createGetSuppliedChildren()).end(); - - return method; - } - - private CodeTree createGetSuppliedChildren() { - ArrayType nodeArray = context.getEnvironment().getTypeUtils().getArrayType(getType(Node.class)); - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startNewArray(nodeArray, null); - for (int i = 0; i < node.getChildExecutions().size(); i++) { - NodeExecutionData execution = node.getChildExecutions().get(i); - if (execution.isShortCircuit()) { - builder.nullLiteral(); - } - if (execution.getChild() == null) { - builder.nullLiteral(); - } else { - builder.tree(accessParent(nodeFieldName(execution))); - } - } - builder.end(); - return builder.build(); - } - - // create specialization - - private CodeTree createCallCreateMethod(SpecializationData specialization, String rootName, LocalContext currentValues) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - TypeMirror specializationType = specializationType(specialization); - if (useLazyClassLoading()) { - builder.startStaticCall(specializationType(specialization), "create"); - } else { - builder.startNew(specializationType); - } - if (rootName != null) { - builder.string(rootName); - } else { - builder.string("root"); - } - if (currentValues != null) { - for (Parameter p : specialization.getSignatureParameters()) { - CodeVariableElement var = createImplicitProfileParameter(p.getSpecification().getExecution(), p.getType()); - if (var != null) { - LocalVariable variable = currentValues.get(p.getLocalName()); - if (variable == null) { - throw new AssertionError("Could not bind cached value " + p.getLocalName() + ": " + currentValues); - } - builder.tree(variable.original().createReference()); - } - } - for (CacheExpression cache : specialization.getCaches()) { - LocalVariable variable = currentValues.get(cache.getParameter().getLocalName()); - if (variable == null) { - throw new AssertionError("Could not bind cached value " + cache.getParameter().getLocalName() + ": " + currentValues); - } - builder.tree(variable.createReference()); - } - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - LocalVariable variable = currentValues.get(assumptionName(assumption)); - if (variable == null) { - throw new AssertionError("Could not bind assumption value " + assumption.getId() + ": " + currentValues); - } - builder.tree(variable.createReference()); - } - } - builder.end(); - - return builder.build(); - } - - private Element createSpecializationCreateMethod(SpecializationData specialization, CodeExecutableElement constructor) { - if (!useLazyClassLoading()) { - return null; - } - - CodeExecutableElement executable = CodeExecutableElement.clone(context.getEnvironment(), constructor); - executable.setReturnType(specializationType(null)); - executable.setSimpleName(CodeNames.of("create")); - executable.getModifiers().add(STATIC); - - CodeTreeBuilder builder = executable.createBuilder(); - builder.startReturn().startNew(specializationType(specialization)); - for (VariableElement parameter : executable.getParameters()) { - builder.string(parameter.getSimpleName().toString()); - } - builder.end().end(); - return executable; - } - - private boolean useLazyClassLoading() { - return options.useLazyClassLoading() && !singleSpecializable; - } - - private static String implicitClassFieldName(NodeExecutionData execution) { - return execution.getName() + "ImplicitType"; - } - - private static String implicitNodeFieldName(NodeExecutionData execution) { - return execution.getName() + "Cast"; - } - - private CodeExecutableElement createSpecializationConstructor(CodeTypeElement clazz, SpecializationData specialization, String constantIndex) { - CodeExecutableElement constructor = new CodeExecutableElement(modifiers(), null, clazz.getSimpleName().toString()); - - constructor.addParameter(new CodeVariableElement(nodeType(node), "root")); - CodeTreeBuilder builder = constructor.createBuilder(); - - if (specialization == null) { - if (constantIndex == null) { - builder.statement("super(index)"); - constructor.addParameter(new CodeVariableElement(getType(int.class), "index")); - } else { - builder.startStatement().startSuperCall().string(constantIndex).end().end(); - } - builder.statement("this.root = root"); - } else { - int index = resolveSpecializationIndex(specialization); - builder.startStatement().startSuperCall().string("root").string(String.valueOf(index)).end().end(); - - for (Parameter p : specialization.getSignatureParameters()) { - NodeExecutionData execution = p.getSpecification().getExecution(); - - CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, p.getType()); - if (implicitProfile != null) { - LocalVariable var = LocalVariable.fromParameter(p).makeGeneric(context); - - String implicitFieldName = implicitProfile.getName(); - if (options.implicitCastOptimization().isDuplicateTail()) { - constructor.addParameter(var.createParameter()); - CodeTree implicitType = TypeSystemCodeGenerator.implicitType(typeSystem, p.getType(), var.createReference()); - builder.startStatement().string("this.").string(implicitFieldName).string(" = ").tree(implicitType).end(); - } else if (options.implicitCastOptimization().isMergeCasts()) { - // use node that supports polymorphism - constructor.addParameter(var.createParameter()); - builder.startStatement().string("this.").string(implicitFieldName).string(" = ").tree(ImplicitCastNodeFactory.create(typeSystem, p.getType(), var.createReference())).end(); - } else { - throw new AssertionError(); - } - } - } - for (CacheExpression cache : specialization.getCaches()) { - String name = cache.getParameter().getLocalName(); - TypeMirror type = cache.getParameter().getType(); - - if (ElementUtils.isAssignable(type, new ArrayCodeTypeMirror(getType(Node.class)))) { - CodeVariableElement var = clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), type, name)); - var.addAnnotationMirror(new CodeAnnotationMirror(context.getDeclaredType(Children.class))); - } else if (ElementUtils.isAssignable(type, getType(Node.class))) { - CodeVariableElement var = clazz.add(new CodeVariableElement(modifiers(PRIVATE), type, name)); - var.addAnnotationMirror(new CodeAnnotationMirror(context.getDeclaredType(Child.class))); - } else { - clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), type, name)); - } - constructor.addParameter(new CodeVariableElement(type, name)); - builder.startStatement().string("this.").string(name).string(" = ").string(name).end(); - } - - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - String name = assumptionName(assumption); - TypeMirror type = assumption.getExpression().getResolvedType(); - CodeVariableElement field = clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), type, name)); - field.addAnnotationMirror(new CodeAnnotationMirror(context.getDeclaredType(CompilationFinal.class))); - constructor.addParameter(new CodeVariableElement(type, name)); - builder.startStatement().string("this.").string(name).string(" = ").string(name).end(); - } - } - - if (constructor.getParameters().isEmpty()) { - // do not generate default constructor - return null; - } - return constructor; - } - - // TODO this logic can be inlined to the parser as soon as the old NodeGen layout is gone - private static int resolveSpecializationIndex(SpecializationData specialization) { - if (specialization.isFallback()) { - return Integer.MAX_VALUE - 1; - } else if (specialization.isUninitialized()) { - return Integer.MAX_VALUE; - } else if (specialization.isPolymorphic()) { - return 0; - } else { - return specialization.getIndex(); - } - } - - private CodeTree createThrowUnsupported(LocalContext currentValues) { - singleSpecializableUnsupportedUsed = true; - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startThrow().startCall("unsupported"); - currentValues.addReferencesTo(builder); - builder.end().end(); - return builder.build(); - } - - private CodeTree createCallNext(CodeTreeBuilder parent, ExecutableTypeData currentType, ExecutableTypeData callType, LocalContext currentValues) { - if (singleSpecializable) { - return createThrowUnsupported(currentValues); - } - CodeTreeBuilder callBuilder = parent.create(); - callBuilder.tree(createCallDelegateExecute(callBuilder, CodeTreeBuilder.singleString("getNext()"), currentValues, currentType, callType)); - nextUsed = true; - return callBuilder.build(); - } - - private CodeTree createCallRemove(String reason, ExecutableTypeData forType, LocalContext currentValues) { - if (singleSpecializable) { - return createThrowUnsupported(currentValues); - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startCall("remove"); - builder.doubleQuote(reason); - currentValues.addReferencesTo(builder, FRAME_VALUE); - builder.end(); - CodeTree call = builder.build(); - - builder = builder.create(); - builder.startReturn(); - builder.tree(expectOrCast(genericType, forType, call)); - builder.end(); - return builder.build(); - } - - private CodeTree createCallDelegate(String methodName, String reason, ExecutableTypeData forType, LocalContext currentValues) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startCall(methodName); - if (reason != null) { - builder.doubleQuote(reason); - } - currentValues.addReferencesTo(builder, FRAME_VALUE); - builder.end(); - - CodeTree expectOrCast = expectOrCast(genericType, forType, builder.build()); - return expectOrCast; - } - - private CodeTree expectOrCast(TypeMirror sourceType, ExecutableTypeData targetType, CodeTree content) { - if (needsUnexpectedResultException(targetType)) { - return expect(sourceType, targetType.getReturnType(), content); - } else { - return cast(sourceType, targetType.getReturnType(), content); - } - } - - private CodeTree cast(TypeMirror sourceType, TypeMirror targetType, CodeTree content) { - if (ElementUtils.needsCastTo(sourceType, targetType) && !isVoid(sourceType)) { - return TypeSystemCodeGenerator.cast(typeSystem, targetType, content); - } else { - return content; - } - } - - private CodeTree expect(TypeMirror sourceType, TypeMirror forType, CodeTree tree) { - if (sourceType == null || ElementUtils.needsCastTo(sourceType, forType)) { - expectedTypes.add(forType); - return TypeSystemCodeGenerator.expect(typeSystem, forType, tree); - } - return tree; - } - - private Set findSpecializedExecutableTypes(NodeExecutionData execution, TypeMirror type) { - if (execution.getChild() == null) { - return Collections.emptySet(); - } - ExecutableTypeData executableType = resolveExecutableType(execution.getChild(), type); - Set executedTypes = new HashSet<>(); - executedTypes.add(executableType); - if (typeSystem.hasImplicitSourceTypes(type)) { - executedTypes.addAll(resolveSpecializedExecutables(execution, typeSystem.lookupSourceTypes(type), options.implicitTypeBoxingOptimization())); - } - return executedTypes; - } - - private ExecutableTypeData resolveExecutableType(NodeChildData child, TypeMirror type) { - int executeWithCount = child.getExecuteWith().size(); - ExecutableTypeData executableType = child.getNodeData().findExecutableType(type, executeWithCount); - if (executableType == null) { - executableType = child.getNodeData().findAnyGenericExecutableType(context, executeWithCount); - } - return executableType; - } - - private boolean hasChildUnexpectedResult(NodeExecutionData execution, TypeMirror type) { - for (ExecutableTypeData executableType : findSpecializedExecutableTypes(execution, type)) { - if (executableType != null && (executableType.hasUnexpectedValue(context) || needsCastTo(executableType.getReturnType(), type))) { - return true; - } - } - return false; - } - - private Element createFastPathExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, List allTypes) { - LocalContext currentLocals = LocalContext.load(this, executedType, Integer.MAX_VALUE); - CodeExecutableElement executable = createExecuteMethod(specialization, executedType, currentLocals, false, Integer.MAX_VALUE); - CodeTreeBuilder builder = executable.createBuilder(); - if (specialization == null) { - if (executedType.getDelegatedTo() == null) { - executable.getModifiers().add(ABSTRACT); - } - } else { - executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); - } - builder.tree(createFastPath(builder, specialization, executedType, allTypes, currentLocals)); - - return executable; - } - - private static final String VARARGS_NAME = "args"; - - private CodeExecutableElement createExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, LocalContext currentLocals, boolean originalOverride, int varArgs) { - TypeMirror returnType = executedType.getReturnType(); - - if (specialization != null) { - currentLocals.loadFastPathState(specialization); - } - - String methodName; - if (originalOverride && executedType.getMethod() != null) { - methodName = executedType.getMethod().getSimpleName().toString(); - } else { - methodName = executedType.getUniqueName(); - } - - CodeExecutableElement executable; - if (originalOverride && executedType.getMethod() != null) { - executable = CodeExecutableElement.clone(context.getEnvironment(), executedType.getMethod()); - executable.getAnnotationMirrors().clear(); - executable.getModifiers().remove(ABSTRACT); - for (VariableElement var : executable.getParameters()) { - ((CodeVariableElement) var).getAnnotationMirrors().clear(); - } - if (executedType.getFrameParameter() != null) { - ((CodeVariableElement) executable.getParameters().get(0)).setName(FRAME_VALUE); - } - - if (executable.isVarArgs()) { - ((CodeVariableElement) executable.getParameters().get(executable.getParameters().size() - 1)).setName(VARARGS_NAME); - } - - renameOriginalParameters(executedType, executable, currentLocals); - } else { - executable = currentLocals.createMethod(modifiers(PUBLIC), returnType, methodName, varArgs, FRAME_VALUE); - } - executable.getThrownTypes().clear(); - - if (needsUnexpectedResultException(executedType)) { - executable.getThrownTypes().add(context.getDeclaredType(UnexpectedResultException.class)); - } - - return executable; - } - - private void renameOriginalParameters(ExecutableTypeData executedType, CodeExecutableElement executable, LocalContext currentLocals) { - // rename varargs parameter - int evaluatedIndex = 0; - for (int executionIndex = 0; executionIndex < node.getExecutionCount(); executionIndex++) { - NodeExecutionData execution = node.getChildExecutions().get(executionIndex); - if (execution.isShortCircuit()) { - if (evaluatedIndex < executedType.getEvaluatedCount()) { - TypeMirror evaluatedType = executedType.getEvaluatedParameters().get(evaluatedIndex); - LocalVariable shortCircuit = currentLocals.getShortCircuit(execution); - if (shortCircuit != null) { - currentLocals.setShortCircuitValue(execution, renameExecutableTypeParameter(executable, executedType, evaluatedIndex, evaluatedType, shortCircuit)); - } - evaluatedIndex++; - } - } - if (evaluatedIndex < executedType.getEvaluatedCount()) { - TypeMirror evaluatedType = executedType.getEvaluatedParameters().get(evaluatedIndex); - LocalVariable value = currentLocals.getValue(execution); - if (value != null) { - currentLocals.setValue(execution, renameExecutableTypeParameter(executable, executedType, evaluatedIndex, evaluatedType, value)); - } - evaluatedIndex++; - } - } - } - - private static LocalVariable renameExecutableTypeParameter(CodeExecutableElement method, ExecutableTypeData executedType, int evaluatedIndex, TypeMirror targetType, LocalVariable var) { - int parameterIndex = executedType.getParameterIndex(evaluatedIndex); - int varArgsIndex = executedType.getVarArgsIndex(parameterIndex); - LocalVariable returnVar = var; - if (varArgsIndex >= 0) { - returnVar = returnVar.accessWith(CodeTreeBuilder.singleString(VARARGS_NAME + "[" + varArgsIndex + "]")); - } else { - ((CodeVariableElement) method.getParameters().get(parameterIndex)).setName(returnVar.getName()); - } - if (!isObject(targetType)) { - returnVar = returnVar.newType(targetType); - } - return returnVar; - } - - private boolean needsUnexpectedResultException(ExecutableTypeData executedType) { - if (!executedType.hasUnexpectedValue(context)) { - return false; - } - - SpecializationData polymorphicSpecialization = node.getPolymorphicSpecialization(); - if (polymorphicSpecialization != null && isSubtypeBoxed(context, polymorphicSpecialization.getReturnType().getType(), executedType.getReturnType())) { - return false; - } else { - return true; - } - } - - private CodeTree createFastPath(CodeTreeBuilder parent, SpecializationData specialization, final ExecutableTypeData executableType, List allTypes, LocalContext currentLocals) { - final CodeTreeBuilder builder = parent.create(); - TypeMirror returnType = executableType.getReturnType(); - - ExecutableTypeData delegate = null; - if (specialization == null) { - delegate = executableType.getDelegatedTo(); - } - - if (delegate == null) { - delegate = findFastPathDelegate((specialization != null ? specialization.getReturnType().getType() : genericType), executableType, allTypes); - } - - int delegateSignatureCount = delegate != null ? delegate.getSignatureParameters().size() : 0; - for (NodeExecutionData execution : node.getChildExecutions()) { - if (specialization == null && delegate != null && execution.getIndex() >= delegateSignatureCount) { - // we just evaluate children for the next delegate - continue; - } else if (specialization != null && delegate != null) { - // skip if already delegated - break; - } - - LocalVariable var = currentLocals.getValue(execution); - if (var == null) { - TypeMirror targetType; - if (specialization == null) { - targetType = node.getGenericType(execution); - } else { - targetType = specialization.findParameterOrDie(execution).getType(); - } - LocalVariable shortCircuit = resolveShortCircuit(specialization, execution, currentLocals); - var = currentLocals.createValue(execution, targetType).nextName(); - builder.tree(createAssignExecuteChild(builder, execution, executableType, var, shortCircuit, currentLocals)); - currentLocals.setValue(execution, var); - } - } - - LocalContext originalValues = currentLocals.copy(); - if (delegate != null) { - builder.tree(createCallDelegateExecute(builder, null, currentLocals, executableType, delegate)); - } else if (specialization == null) { - // nothing to do. abstract anyway - } else if (specialization.isPolymorphic()) { - builder.tree(createCallNext(builder, executableType, node.getGenericExecutableType(executableType), currentLocals)); - } else if (specialization.isUninitialized()) { - builder.startReturn().tree(createCallDelegate("uninitialized", null, executableType, currentLocals)).end(); - } else { - SpecializationGroup group = SpecializationGroup.create(specialization); - SpecializationBody executionFactory = new SpecializationBody(true, true) { - @Override - public CodeTree createBody(SpecializationData s, LocalContext values) { - return createFastPathExecute(builder, executableType, s, values); - } - }; - builder.tree(createGuardAndCast(group, returnType, currentLocals, executionFactory)); - if (hasFallthrough(group, returnType, originalValues, true, null) || group.getSpecialization().isFallback()) { - builder.tree(createCallNext(builder, executableType, node.getGenericExecutableType(executableType), originalValues)); - } - } - return builder.build(); - } - - private CodeTree createCallDelegateExecute(final CodeTreeBuilder parent, CodeTree receiver, LocalContext currentLocals, ExecutableTypeData source, ExecutableTypeData delegate) { - CodeTreeBuilder callBuilder = parent.create(); - - if (singleSpecializable && delegate.getMethod() != null) { - callBuilder.startCall(receiver, delegate.getMethod().getSimpleName().toString()); - } else { - callBuilder.startCall(receiver, delegate.getUniqueName()); - } - callBuilder.trees(bindExecuteMethodParameters(null, delegate, currentLocals)); - callBuilder.end(); - CodeTree call = expectOrCast(delegate.getReturnType(), source, callBuilder.build()); - - CodeTreeBuilder returnBuilder = parent.create(); - if (isVoid(source.getReturnType())) { - returnBuilder.statement(call); - returnBuilder.returnStatement(); - } else if (isVoid(delegate.getReturnType())) { - returnBuilder.statement(call); - returnBuilder.returnDefault(); - } else { - returnBuilder.startReturn().tree(call).end(); - } - - CodeTreeBuilder builder = parent.create(); - - if (!needsUnexpectedResultException(source) && needsUnexpectedResultException(delegate)) { - builder.startTryBlock(); - builder.tree(returnBuilder.build()); - builder.end().startCatchBlock(context.getType(UnexpectedResultException.class), "ex"); - if (!isVoid(source.getReturnType())) { - builder.startReturn().tree(cast(context.getType(Object.class), source.getReturnType(), CodeTreeBuilder.singleString("ex.getResult()"))).end(); - } - builder.end(); - } else { - builder.tree(returnBuilder.build()); - } - return builder.build(); - } - - private ExecutableTypeData findFastPathDelegate(TypeMirror targetType, ExecutableTypeData executableType, List allTypes) { - if (typeEquals(executableType.getReturnType(), targetType)) { - // type matches look for even better delegates - for (ExecutableTypeData type : allTypes) { - if (typeEquals(type.getReturnType(), targetType) && executableType.sameParameters(type)) { - if (type != executableType) { - return type; - } - } - } - return null; - } else { - for (ExecutableTypeData type : allTypes) { - if (typeEquals(type.getReturnType(), targetType) && executableType.sameParameters(type)) { - return type; - } - } - int executableIndex = allTypes.indexOf(executableType); - int compareIndex = 0; - for (ExecutableTypeData type : allTypes) { - if (executableIndex != compareIndex && executableType.sameParameters(type)) { - int result = ExecutableTypeData.compareType(context, type.getReturnType(), executableType.getReturnType()); - if (result < 0) { - return type; - } else if (result == 0 && executableIndex < compareIndex) { - return type; - } - } - compareIndex++; - } - return null; - } - } - - private LocalVariable resolveShortCircuit(SpecializationData specialization, NodeExecutionData execution, LocalContext currentLocals) { - LocalVariable shortCircuit = null; - if (execution.isShortCircuit()) { - shortCircuit = currentLocals.getShortCircuit(execution); - - if (shortCircuit == null) { - SpecializationData resolvedSpecialization = specialization; - if (specialization == null) { - resolvedSpecialization = node.getGenericSpecialization(); - } - ShortCircuitData shortCircuitData = resolvedSpecialization.getShortCircuits().get(calculateShortCircuitIndex(execution)); - CodeTree access = callTemplateMethod(accessParent(null), shortCircuitData, currentLocals); - shortCircuit = currentLocals.createShortCircuitValue(execution).accessWith(access); - } else { - CodeTree access = shortCircuit.createReference(); - shortCircuit = shortCircuit.nextName().accessWith(access); - } - } - return shortCircuit; - } - - private int calculateShortCircuitIndex(NodeExecutionData execution) { - int shortCircuitIndex = 0; - for (NodeExecutionData otherExectuion : node.getChildExecutions()) { - if (otherExectuion.isShortCircuit()) { - if (otherExectuion == execution) { - break; - } - shortCircuitIndex++; - } - } - return shortCircuitIndex; - } - - private CodeTree createFastPathExecute(CodeTreeBuilder parent, final ExecutableTypeData forType, SpecializationData specialization, LocalContext currentValues) { - CodeTreeBuilder builder = parent.create(); - int ifCount = 0; - if (specialization.isFallback()) { - builder.startIf().startCall("guardFallback"); - if (node.isFrameUsedByAnyGuard()) { - if (currentValues.get(FRAME_VALUE) != null) { - builder.string(FRAME_VALUE); - } else { - builder.nullLiteral(); - } - } - currentValues.addReferencesTo(builder); - - builder.end(); - builder.end(); - builder.startBlock(); - ifCount++; - } - CodeTreeBuilder execute = builder.create(); - - if (!specialization.getAssumptionExpressions().isEmpty()) { - builder.startTryBlock(); - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - LocalVariable assumptionVar = currentValues.get(assumptionName(assumption)); - if (assumptionVar == null) { - throw new AssertionError("Could not resolve assumption var " + currentValues); - } - builder.startStatement().startCall("check").tree(assumptionVar.createReference()).end().end(); - } - builder.end().startCatchBlock(getType(InvalidAssumptionException.class), "ae"); - builder.startReturn(); - List assumptionIds = new ArrayList<>(); - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - assumptionIds.add(assumption.getId()); - } - builder.tree(createCallDelegate("removeThis", String.format("Assumption %s invalidated", assumptionIds), forType, currentValues)); - builder.end(); - builder.end(); - } - - if (specialization.getMethod() == null) { - execute.startReturn(); - execute.startCall("unsupported"); - currentValues.addReferencesTo(execute, FRAME_VALUE); - execute.end(); - execute.end(); - } else { - boolean doReturn = !isVoid(specialization.getMethod().getReturnType()); - if (doReturn) { - execute.startReturn(); - } else { - execute.startStatement(); - } - execute.tree(callTemplateMethod(accessParent(null), specialization, currentValues)); - execute.end(); - if (!doReturn) { - if (isVoid(forType.getReturnType())) { - execute.returnStatement(); - } else { - execute.startReturn(); - execute.defaultValue(forType.getReturnType()); - execute.end(); - } - } - } - builder.tree(createFastPathTryCatchRewriteException(specialization, forType, currentValues, execute.build())); - builder.end(ifCount); - return builder.build(); - } - - private CodeTree createGuardAndCast(SpecializationGroup group, TypeMirror forType, LocalContext currentValues, SpecializationBody execution) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - Set castGuards; - if (execution.needsCastedValues()) { - castGuards = null; // cast all - } else { - castGuards = new HashSet<>(); - for (TypeGuard castGuard : group.getTypeGuards()) { - if (isTypeGuardUsedInAnyGuardOrCacheBelow(group, currentValues, castGuard, execution.isFastPath())) { - castGuards.add(castGuard); - } - } - } - - SpecializationData specialization = group.getSpecialization(); - CodeTree[] checkAndCast = createTypeCheckAndLocals(specialization, group.getTypeGuards(), castGuards, currentValues, execution); - - CodeTree check = checkAndCast[0]; - CodeTree cast = checkAndCast[1]; - - List elseGuardExpressions = group.findElseConnectableGuards(); - List guardExpressions = new ArrayList<>(group.getGuards()); - guardExpressions.removeAll(elseGuardExpressions); - CodeTree[] methodGuardAndAssertions = createMethodGuardCheck(guardExpressions, specialization, currentValues, execution.isFastPath()); - CodeTree methodGuards = methodGuardAndAssertions[0]; - CodeTree guardAssertions = methodGuardAndAssertions[1]; - - int ifCount = 0; - if (!check.isEmpty()) { - builder.startIf(); - builder.tree(check).end(); - builder.startBlock(); - ifCount++; - } - if (!cast.isEmpty()) { - builder.tree(cast); - } - boolean elseIf = !elseGuardExpressions.isEmpty(); - if (!methodGuards.isEmpty()) { - builder.startIf(elseIf); - builder.tree(methodGuards).end(); - builder.startBlock(); - ifCount++; - } else if (elseIf) { - builder.startElseBlock(); - ifCount++; - } - if (!guardAssertions.isEmpty()) { - builder.tree(guardAssertions); - } - - boolean reachable = isReachableGroup(group, ifCount); - if (reachable) { - for (SpecializationGroup child : group.getChildren()) { - builder.tree(createGuardAndCast(child, forType, currentValues.copy(), execution)); - } - if (specialization != null) { - builder.tree(execution.createBody(specialization, currentValues)); - } - } - builder.end(ifCount); - - return builder.build(); - } - - private static boolean isReachableGroup(SpecializationGroup group, int ifCount) { - if (ifCount != 0) { - return true; - } - SpecializationGroup previous = group.getPreviousGroup(); - if (previous == null || previous.findElseConnectableGuards().isEmpty()) { - return true; - } - - /* - * Hacky else case. In this case the specialization is not reachable due to previous else - * branch. This is only true if the minimum state is not checked. - */ - if (previous.getGuards().size() == 1 && previous.getTypeGuards().isEmpty() && - (previous.getParent() == null || previous.getMaxSpecializationIndex() != previous.getParent().getMaxSpecializationIndex())) { - return false; - } - - return true; - } - - private boolean isTypeGuardUsedInAnyGuardOrCacheBelow(SpecializationGroup group, LocalContext currentValues, TypeGuard typeGuard, boolean fastPath) { - String localName = currentValues.getValue(typeGuard.getSignatureIndex()).getName(); - - SpecializationData specialization = group.getSpecialization(); - for (GuardExpression guard : group.getGuards()) { - if (isVariableBoundIn(specialization, guard.getExpression(), localName, currentValues)) { - return true; - } - } - if (!fastPath && specialization != null) { - for (CacheExpression cache : specialization.getCaches()) { - if (isVariableBoundIn(specialization, cache.getExpression(), localName, currentValues)) { - return true; - } - } - } - - for (SpecializationGroup child : group.getChildren()) { - if (isTypeGuardUsedInAnyGuardOrCacheBelow(child, currentValues, typeGuard, fastPath)) { - return true; - } - } - - return false; - } - - private static boolean isVariableBoundIn(SpecializationData specialization, DSLExpression expression, String localName, LocalContext currentValues) throws AssertionError { - Map boundValues = bindExpressionValues(expression, specialization, currentValues); - for (Variable var : expression.findBoundVariables()) { - LocalVariable target = boundValues.get(var); - if (target != null && localName.equals(target.getName())) { - return true; - } - } - return false; - } - - private CodeExecutableElement createExecuteChildMethod(NodeExecutionData execution, TypeMirror targetType) { - if (!usedExecuteChildMethods.contains(execution)) { - return null; - } - - LocalContext locals = LocalContext.load(this, createSpecializationNodeSignature(0), Integer.MAX_VALUE); - - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType, executeChildMethodName(execution, targetType), Integer.MAX_VALUE, FRAME_VALUE); - if (hasChildUnexpectedResult(execution, targetType)) { - method.getThrownTypes().add(getType(UnexpectedResultException.class)); - } - - CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, targetType); - if (implicitProfile != null) { - method.addParameter(implicitProfile); - } - - for (int i = 0; i < execution.getChild().getExecuteWith().size(); i++) { - NodeExecutionData executeWith = node.getChildExecutions().get(i); - LocalVariable var = locals.createValue(executeWith, genericType); - method.addParameter(var.createParameter()); - locals.setValue(executeWith, var); - } - - CodeTreeBuilder builder = method.createBuilder(); - CodeTree executeChild = createExecuteChild(execution, locals.createValue(execution, targetType), locals, true); - if (executeChild.isSingleLine()) { - builder.statement(executeChild); - } else { - builder.tree(executeChild); - } - return method; - } - - private CodeVariableElement createImplicitProfileParameter(NodeExecutionData execution, TypeMirror targetType) { - if (typeSystem.hasImplicitSourceTypes(targetType)) { - if (typeEquals(node.getGenericType(execution), targetType)) { - return null; - } - - switch (options.implicitCastOptimization()) { - case NONE: - return null; - case DUPLICATE_TAIL: - return new CodeVariableElement(getType(Class.class), implicitClassFieldName(execution)); - case MERGE_CASTS: - return new CodeVariableElement(ImplicitCastNodeFactory.type(typeSystem, targetType), implicitNodeFieldName(execution)); - } - } - return null; - } - - private boolean isExecuteChildShared(NodeExecutionData execution, TypeMirror targetType) { - if (isVoid(targetType)) { - return false; - } else if (isObject(targetType)) { - return resolvePolymorphicExecutables(execution).size() >= 1; - } else { - if (!isTypeBoxingOptimized(options.monomorphicTypeBoxingOptimization(), targetType)) { - return false; - } - if (!typeSystem.hasImplicitSourceTypes(targetType)) { - return false; - } - - int uses = 0; - for (SpecializationData specialization : node.getSpecializations()) { - List parameters = specialization.findByExecutionData(execution); - for (Parameter parameter : parameters) { - if (targetType.equals(parameter.getType())) { - uses++; - } - } - } - if (uses > 1) { - return resolveSpecializedExecutables(execution, typeSystem.lookupSourceTypes(targetType), options.implicitTypeBoxingOptimization()).size() > 1; - } else { - return false; - } - } - } - - private CodeTree createAssignExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData type, LocalVariable targetValue, LocalVariable shortCircuit, - LocalContext currentValues) { - CodeTreeBuilder builder = parent.create(); - boolean hasUnexpected = hasChildUnexpectedResult(execution, targetValue.getTypeMirror()); - - CodeTree executeChild; - if (isExecuteChildShared(execution, targetValue.getTypeMirror())) { - executeChild = createCallSharedExecuteChild(execution, targetValue, currentValues); - } else { - executeChild = createExecuteChild(execution, targetValue, currentValues, false); - } - - builder.tree(createTryExecuteChild(targetValue, executeChild, shortCircuit == null, hasUnexpected)); - - if (shortCircuit != null) { - currentValues.setShortCircuitValue(execution, shortCircuit.accessWith(null)); - } - - builder.end(); - if (hasUnexpected) { - builder.startCatchBlock(getType(UnexpectedResultException.class), "ex"); - LocalContext slowPathValues = currentValues.copy(); - slowPathValues.setValue(execution, targetValue.makeGeneric(context).accessWith(CodeTreeBuilder.singleString("ex.getResult()"))); - - ExecutableTypeData delegateType = node.getGenericExecutableType(type); - boolean found = false; - for (NodeExecutionData otherExecution : node.getChildExecutions()) { - if (found) { - LocalVariable childEvaluatedValue = slowPathValues.createValue(otherExecution, genericType); - LocalVariable genericShortCircuit = resolveShortCircuit(null, otherExecution, slowPathValues); - builder.tree(createAssignExecuteChild(builder, otherExecution, delegateType, childEvaluatedValue, genericShortCircuit, slowPathValues)); - slowPathValues.setValue(otherExecution, childEvaluatedValue); - } else { - // skip forward already evaluated - found = execution == otherExecution; - } - } - builder.tree(createCallNext(builder, type, delegateType, slowPathValues)); - builder.end(); - } - - return createShortCircuit(targetValue, shortCircuit, builder.build()); - } - - private static CodeTree createShortCircuit(LocalVariable targetValue, LocalVariable shortCircuitValue, CodeTree tryExecute) { - if (shortCircuitValue == null) { - return tryExecute; - } - - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - builder.tree(shortCircuitValue.createDeclaration(shortCircuitValue.createReference())); - builder.tree(targetValue.createDeclaration(builder.create().defaultValue(targetValue.getTypeMirror()).build())); - - builder.startIf().string(shortCircuitValue.getName()).end().startBlock(); - builder.tree(tryExecute); - builder.end(); - - return builder.build(); - } - - private static CodeTree createTryExecuteChild(LocalVariable value, CodeTree executeChild, boolean needDeclaration, boolean hasTry) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - boolean hasDeclaration = false; - if ((hasTry || !executeChild.isSingleLine()) && needDeclaration) { - builder.tree(value.createDeclaration(null)); - hasDeclaration = true; - } - - if (hasTry) { - builder.startTryBlock(); - } else { - builder.startGroup(); - } - - if (executeChild.isSingleLine()) { - builder.startStatement(); - if (hasDeclaration || !needDeclaration) { - builder.tree(executeChild); - } else { - builder.type(value.getTypeMirror()).string(" ").tree(executeChild); - } - builder.end(); - } else { - builder.tree(executeChild); - } - - builder.end(); - - return builder.build(); - } - - private CodeTree createCallSharedExecuteChild(NodeExecutionData execution, LocalVariable targetValue, LocalContext currentValues) { - if (!isExecuteChildShared(execution, targetValue.getTypeMirror())) { - throw new AssertionError("Execute child not shared with method but called."); - } - usedExecuteChildMethods.add(execution); - - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.tree(targetValue.createReference()).string(" = "); - builder.startCall(executeChildMethodName(execution, targetValue.getTypeMirror())); - if (currentValues.get(FRAME_VALUE) == null) { - builder.nullLiteral(); - } else { - builder.string(FRAME_VALUE); - } - - CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, targetValue.getTypeMirror()); - if (implicitProfile != null) { - builder.string(implicitProfile.getName()); - } - for (int i = 0; i < execution.getChild().getExecuteWith().size(); i++) { - builder.tree(currentValues.getValue(i).createReference()); - } - builder.end(); - return builder.build(); - } - - private CodeTree createExecuteChild(NodeExecutionData execution, LocalVariable target, LocalContext currentValues, boolean shared) { - final CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - CodeTree assignment = createAssignmentStart(target, shared); - - final Set executableTypes = findSpecializedExecutableTypes(execution, target.getTypeMirror()); - if (executableTypes.isEmpty()) { - throw new AssertionError(); // cannot execute child - } else if (executableTypes.size() == 1 && !typeSystem.hasImplicitSourceTypes(target.getTypeMirror())) { - ExecutableTypeData executableType = executableTypes.iterator().next(); - if (isObject(target.getTypeMirror()) && executableType.getEvaluatedCount() == 0) { - return createPolymorphicExecuteChild(execution, target, currentValues, shared); - } else { - builder.tree(assignment); - builder.tree(createSingleExecute(execution, target, currentValues, executableType)); - } - } else { - if (options.implicitCastOptimization().isNone()) { - throw new AssertionError("findSpecializedExecutableTypes is always 1 if implicit cast opt is disabled"); - } else if (options.implicitCastOptimization().isDuplicateTail()) { - builder.tree(createExecuteChildDuplicateTail(builder, execution, assignment, target, currentValues)); - } else if (options.implicitCastOptimization().isMergeCasts()) { - // TODO - throw new UnsupportedOperationException(); - } else { - throw new AssertionError(); - } - } - return builder.build(); - } - - private CodeTree createSingleExecute(NodeExecutionData execution, LocalVariable target, LocalContext currentValues, ExecutableTypeData executableType) { - CodeTree execute = callExecuteMethod(execution, executableType, currentValues); - return expect(executableType.getReturnType(), target.getTypeMirror(), execute); - } - - private CodeTree createPolymorphicExecuteChild(NodeExecutionData execution, LocalVariable target, LocalContext currentValues, boolean shared) throws AssertionError { - ExecutableTypeData genericExecutableType = execution.getChild().getNodeData().findAnyGenericExecutableType(context, execution.getChild().getExecuteWith().size()); - if (genericExecutableType == null) { - throw new AssertionError("At least one generic executable method must be available."); - } - - List specializedExecutables = resolvePolymorphicExecutables(execution); - Collections.sort(specializedExecutables, new Comparator() { - public int compare(ExecutableTypeData o1, ExecutableTypeData o2) { - return compareType(o1.getReturnType(), o2.getReturnType()); - } - }); - - CodeTree assignment = createAssignmentStart(target, shared); - CodeTree executeGeneric = createSingleExecute(execution, target, currentValues, genericExecutableType); - - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - if (specializedExecutables.isEmpty()) { - builder.tree(assignment); - builder.tree(executeGeneric); - } else { - final CodeTreeBuilder polyChainBuilder = builder.create(); - final String profileField = polymorphicTypeProfileFieldName(execution); - final String valueFieldName = "_value"; - final String typeFieldName = "_type"; - - builder.declaration(getType(Class.class), profileField, accessParent(profileField)); - - boolean encounteredUnexpectedResult = false; - boolean hasSpecializedTypes = false; - for (ExecutableTypeData executableType : specializedExecutables) { - hasSpecializedTypes = polyChainBuilder.startIf(hasSpecializedTypes); - polyChainBuilder.string(profileField); - polyChainBuilder.string(" == ").typeLiteral(executableType.getReturnType()); - polyChainBuilder.end(); - polyChainBuilder.startBlock(); - polyChainBuilder.startStatement(); - polyChainBuilder.tree(assignment); - polyChainBuilder.tree(createSingleExecute(execution, target, currentValues, executableType)).end(); - polyChainBuilder.end(); - encounteredUnexpectedResult |= executableType.hasUnexpectedValue(context); - } - - // else if null -> specialize - polyChainBuilder.startElseIf().string(profileField).string(" == null").end(); - polyChainBuilder.startBlock(); - polyChainBuilder.tree(createTransferToInterpreterAndInvalidate()); - polyChainBuilder.declaration(context.getType(Class.class), typeFieldName, polyChainBuilder.create().typeLiteral(genericType).build()); - polyChainBuilder.startTryBlock(); - polyChainBuilder.declaration(genericExecutableType.getReturnType(), valueFieldName, executeGeneric); - - hasSpecializedTypes = false; - for (ExecutableTypeData executableType : specializedExecutables) { - hasSpecializedTypes = polyChainBuilder.startIf(hasSpecializedTypes); - polyChainBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, executableType.getReturnType(), CodeTreeBuilder.singleString(valueFieldName))); - polyChainBuilder.end(); - polyChainBuilder.startBlock(); - polyChainBuilder.startStatement().string(typeFieldName).string(" = ").typeLiteral(executableType.getReturnType()).end(); - polyChainBuilder.end(); - } - polyChainBuilder.startElseBlock(); - polyChainBuilder.startStatement().string(typeFieldName).string(" = ").typeLiteral(genericType).end(); - polyChainBuilder.end(); - polyChainBuilder.startReturn().string(valueFieldName).end(); - - polyChainBuilder.end().startFinallyBlock(); - polyChainBuilder.startStatement().tree(accessParent(profileField)).string(" = ").string(typeFieldName).end(); - polyChainBuilder.end(); - polyChainBuilder.end(); - - // else -> execute generic - polyChainBuilder.startElseBlock(); - polyChainBuilder.startStatement().tree(assignment).tree(executeGeneric).end(); - polyChainBuilder.end(); - - CodeTree executePolymorphic = polyChainBuilder.build(); - if (encounteredUnexpectedResult) { - builder.startTryBlock(); - builder.tree(executePolymorphic); - builder.end(); - builder.startCatchBlock(getType(UnexpectedResultException.class), "ex"); - builder.startStatement().tree(accessParent(profileField)).string(" = ").typeLiteral(genericType).end(); - builder.startReturn().string("ex.getResult()").end(); - builder.end(); - } else { - builder.tree(executePolymorphic); - } - } - return builder.build(); - } - - private List resolvePolymorphicExecutables(NodeExecutionData execution) { - if (singleSpecializable) { - return Collections.emptyList(); - } - Set specializedTypes = new HashSet<>(); - for (TypeMirror type : node.findSpecializedTypes(execution)) { - specializedTypes.addAll(typeSystem.lookupSourceTypes(type)); - } - return resolveSpecializedExecutables(execution, specializedTypes, options.polymorphicTypeBoxingElimination()); - } - - private static CodeTree createAssignmentStart(LocalVariable target, boolean shared) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - if (shared) { - builder.string("return "); - } else { - builder.string(target.getName()).string(" = "); - } - return builder.build(); - } - - private CodeTree createExecuteChildDuplicateTail(CodeTreeBuilder parent, NodeExecutionData execution, CodeTree assignment, LocalVariable target, LocalContext currentValues) { - CodeTreeBuilder builder = parent.create(); - List sourceTypes = typeSystem.lookupSourceTypes(target.getTypeMirror()); - String implicitClassFieldName = implicitClassFieldName(execution); - List executableTypes = resolveSpecializedExecutables(execution, sourceTypes, options.implicitTypeBoxingOptimization()); - - boolean elseIf = false; - for (ExecutableTypeData executableType : executableTypes) { - elseIf = builder.startIf(elseIf); - builder.string(implicitClassFieldName).string(" == ").typeLiteral(executableType.getReturnType()); - builder.end(); - builder.startBlock(); - builder.startStatement().tree(assignment); - - CodeTree execute = callExecuteMethod(execution, executableType, currentValues); - ImplicitCastData cast = typeSystem.lookupCast(executableType.getReturnType(), target.getTypeMirror()); - if (cast != null) { - execute = callMethod(null, cast.getMethod(), execute); - } - builder.tree(execute); - builder.end(); - builder.end(); - } - - if (!executableTypes.isEmpty()) { - builder.startElseBlock(); - } - - LocalVariable genericValue = target.makeGeneric(context).nextName(); - builder.tree(createAssignExecuteChild(builder, execution, node.getGenericExecutableType(null), genericValue, null, currentValues)); - if (executableTypes.size() == sourceTypes.size()) { - builder.startThrow().startNew(getType(UnexpectedResultException.class)).tree(genericValue.createReference()).end().end(); - } else { - builder.startStatement().tree(assignment); - builder.tree(TypeSystemCodeGenerator.implicitExpect(typeSystem, target.getTypeMirror(), genericValue.createReference(), implicitClassFieldName)); - builder.end(); - } - - if (!executableTypes.isEmpty()) { - builder.end(); - } - return builder.build(); - } - - private CodeTree createFastPathTryCatchRewriteException(SpecializationData specialization, ExecutableTypeData forType, LocalContext currentValues, CodeTree execution) { - if (specialization.getExceptions().isEmpty()) { - return execution; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startTryBlock(); - builder.tree(execution); - TypeMirror[] exceptionTypes = new TypeMirror[specialization.getExceptions().size()]; - for (int i = 0; i < exceptionTypes.length; i++) { - exceptionTypes[i] = specialization.getExceptions().get(i).getJavaClass(); - } - builder.end().startCatchBlock(exceptionTypes, "ex"); - builder.startStatement().tree(accessParent(excludedFieldName(specialization))).string(" = true").end(); - builder.tree(createCallRemove("threw rewrite exception", forType, currentValues)); - builder.end(); - return builder.build(); - } - - private CodeTree[] createMethodGuardCheck(List guardExpressions, SpecializationData specialization, LocalContext currentValues, boolean fastPath) { - CodeTreeBuilder expressionBuilder = CodeTreeBuilder.createBuilder(); - CodeTreeBuilder assertionBuilder = CodeTreeBuilder.createBuilder(); - String and = ""; - for (GuardExpression guard : guardExpressions) { - DSLExpression expression = guard.getExpression(); - - Map resolvedBindings = castBoundTypes(bindExpressionValues(expression, specialization, currentValues)); - CodeTree expressionCode = DSLExpressionGenerator.write(expression, accessParent(null), resolvedBindings); - - if (!specialization.isDynamicParameterBound(expression) && fastPath) { - /* - * Guards where no dynamic parameters are bound can just be executed on the fast - * path. - */ - assertionBuilder.startAssert().tree(expressionCode).end(); - } else { - expressionBuilder.string(and); - expressionBuilder.tree(expressionCode); - and = " && "; - } - } - return new CodeTree[]{expressionBuilder.build(), assertionBuilder.build()}; - } - - private static Map castBoundTypes(Map bindings) { - Map resolvedBindings = new HashMap<>(); - for (Variable variable : bindings.keySet()) { - LocalVariable localVariable = bindings.get(variable); - CodeTree resolved = localVariable.createReference(); - TypeMirror sourceType = localVariable.getTypeMirror(); - TypeMirror targetType = variable.getResolvedTargetType(); - if (targetType == null) { - targetType = variable.getResolvedType(); - } - if (!ElementUtils.isAssignable(sourceType, targetType)) { - resolved = CodeTreeBuilder.createBuilder().cast(targetType, resolved).build(); - } - resolvedBindings.put(variable, resolved); - } - return resolvedBindings; - } - - private static Map bindExpressionValues(DSLExpression expression, SpecializationData specialization, LocalContext currentValues) throws AssertionError { - Map bindings = new HashMap<>(); - - Set boundVariables = expression.findBoundVariables(); - if (specialization == null && !boundVariables.isEmpty()) { - throw new AssertionError("Cannot bind guard variable in non-specialization group. yet."); - } - - // resolve bindings for local context - for (Variable variable : boundVariables) { - Parameter resolvedParameter = specialization.findByVariable(variable.getResolvedVariable()); - if (resolvedParameter != null) { - LocalVariable localVariable; - if (resolvedParameter.getSpecification().isSignature()) { - NodeExecutionData execution = resolvedParameter.getSpecification().getExecution(); - localVariable = currentValues.getValue(execution); - } else { - localVariable = currentValues.get(resolvedParameter.getLocalName()); - } - if (localVariable != null) { - bindings.put(variable, localVariable); - } - } - } - return bindings; - } - - private CodeTree[] createTypeCheckAndLocals(SpecializationData specialization, List typeGuards, Set castGuards, LocalContext currentValues, - SpecializationBody specializationExecution) { - CodeTreeBuilder checksBuilder = CodeTreeBuilder.createBuilder(); - CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder(); - for (TypeGuard typeGuard : typeGuards) { - int signatureIndex = typeGuard.getSignatureIndex(); - LocalVariable value = currentValues.getValue(signatureIndex); - TypeMirror targetType = typeGuard.getType(); - if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) { - continue; - } - NodeExecutionData execution = node.getChildExecutions().get(signatureIndex); - if (!checksBuilder.isEmpty()) { - checksBuilder.string(" && "); - } - - CodeTreeBuilder checkBuilder = checksBuilder.create(); - CodeTreeBuilder castBuilder = checksBuilder.create(); - - LocalVariable shortCircuit = currentValues.getShortCircuit(execution); - if (shortCircuit != null) { - checkBuilder.string("("); - CodeTreeBuilder referenceBuilder = checkBuilder.create(); - if (!ElementUtils.isPrimitive(shortCircuit.getTypeMirror())) { - referenceBuilder.string("(boolean) "); - } - referenceBuilder.tree(shortCircuit.createReference()); - checkBuilder.string("!").tree(referenceBuilder.build()); - checkBuilder.string(" || "); - castBuilder.tree(referenceBuilder.build()).string(" ? "); - } - - List sourceTypes = typeSystem.lookupByTargetType(targetType); - CodeTree valueReference = value.createReference(); - if (sourceTypes.isEmpty()) { - checkBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, targetType, value.createReference())); - castBuilder.tree(TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference)); - } else { - ImplicitCastOptimization opt = options.implicitCastOptimization(); - if (specializationExecution.isFastPath() && !opt.isNone()) { - if (opt.isDuplicateTail()) { - String typeHintField = implicitClassFieldName(execution); - checkBuilder.tree(TypeSystemCodeGenerator.implicitCheck(typeSystem, targetType, valueReference, typeHintField)); - castBuilder.tree(TypeSystemCodeGenerator.implicitCast(typeSystem, targetType, valueReference, typeHintField)); - } else if (opt.isMergeCasts()) { - checkBuilder.tree(ImplicitCastNodeFactory.check(implicitNodeFieldName(execution), valueReference)); - castBuilder.tree(ImplicitCastNodeFactory.cast(implicitNodeFieldName(execution), valueReference)); - } else { - throw new AssertionError("implicit cast opt"); - } - } else { - checkBuilder.tree(TypeSystemCodeGenerator.implicitCheck(typeSystem, targetType, valueReference, null)); - castBuilder.tree(TypeSystemCodeGenerator.implicitCast(typeSystem, targetType, valueReference, null)); - } - } - - if (shortCircuit != null) { - checkBuilder.string(")"); - castBuilder.string(" : ").defaultValue(targetType); - } - - if (castGuards == null || castGuards.contains(typeGuard)) { - LocalVariable castVariable = currentValues.getValue(execution).nextName().newType(typeGuard.getType()).accessWith(null); - currentValues.setValue(execution, castVariable); - localsBuilder.tree(castVariable.createDeclaration(castBuilder.build())); - } - - checksBuilder.tree(checkBuilder.build()); - } - - if (specialization != null && !specializationExecution.isFastPath()) { - for (CacheExpression cache : specialization.getCaches()) { - if (specialization.isCacheBoundByGuard(cache)) { - initializeCache(localsBuilder, specialization, cache, currentValues); - } - } - } - - return new CodeTree[]{checksBuilder.build(), localsBuilder.build()}; - } - - private void initializeCache(CodeTreeBuilder builder, SpecializationData specialization, CacheExpression cache, LocalContext currentValues) { - CodeTree initializer = DSLExpressionGenerator.write(cache.getExpression(), accessParent(null), castBoundTypes(bindExpressionValues(cache.getExpression(), specialization, currentValues))); - String name = cache.getParameter().getLocalName(); - // multiple specializations might use the same name - String varName = name + specialization.getIndex(); - TypeMirror type = cache.getParameter().getType(); - builder.declaration(type, varName, initializer); - currentValues.set(name, new LocalVariable(type, varName, null, null)); - } - - public static final class LocalContext { - - private final NodeGenFactory factory; - private final Map values = new HashMap<>(); - - private LocalContext(NodeGenFactory factory) { - this.factory = factory; - } - - public void loadFastPathState(SpecializationData specialization) { - for (CacheExpression cache : specialization.getCaches()) { - Parameter cacheParameter = cache.getParameter(); - String name = cacheParameter.getVariableElement().getSimpleName().toString(); - set(cacheParameter.getLocalName(), new LocalVariable(cacheParameter.getType(), name, CodeTreeBuilder.singleString("this." + name), null)); - } - - for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { - String name = assumptionName(assumption); - TypeMirror type = assumption.getExpression().getResolvedType(); - set(name, new LocalVariable(type, name, CodeTreeBuilder.singleString("this." + name), null)); - } - } - - public CodeExecutableElement createMethod(Set modifiers, TypeMirror returnType, String name, int varArgsThreshold, String... optionalArguments) { - CodeExecutableElement method = new CodeExecutableElement(modifiers, returnType, name); - addParametersTo(method, varArgsThreshold, optionalArguments); - return method; - } - - public static LocalContext load(NodeGenFactory factory, ExecutableTypeData type, int varargsThreshold) { - LocalContext context = new LocalContext(factory); - context.loadEvaluatedValues(type, varargsThreshold); - return context; - } - - private void loadEvaluatedValues(ExecutableTypeData executedType, int varargsThreshold) { - TypeMirror frame = executedType.getFrameParameter(); - if (frame == null) { - removeValue(FRAME_VALUE); - } else { - set(FRAME_VALUE, new LocalVariable(frame, FRAME_VALUE, null, null)); - } - for (NodeFieldData field : factory.node.getFields()) { - String fieldName = fieldValueName(field); - values.put(fieldName, new LocalVariable(field.getType(), fieldName, factory.accessParent(field.getName()), null)); - } - boolean varargs = needsVarargs(false, varargsThreshold); - List evaluatedParameter = executedType.getEvaluatedParameters(); - int evaluatedIndex = 0; - for (int executionIndex = 0; executionIndex < factory.node.getExecutionCount(); executionIndex++) { - NodeExecutionData execution = factory.node.getChildExecutions().get(executionIndex); - if (execution.isShortCircuit()) { - if (evaluatedIndex < executedType.getEvaluatedCount()) { - TypeMirror evaluatedType = evaluatedParameter.get(evaluatedIndex); - LocalVariable shortCircuit = createShortCircuitValue(execution).newType(evaluatedType); - if (varargs) { - shortCircuit = shortCircuit.accessWith(createReadVarargs(evaluatedIndex)); - } - values.put(shortCircuit.getName(), shortCircuit.makeOriginal()); - evaluatedIndex++; - } - } - if (evaluatedIndex < executedType.getEvaluatedCount()) { - TypeMirror evaluatedType = evaluatedParameter.get(evaluatedIndex); - LocalVariable value = createValue(execution, evaluatedType); - if (varargs) { - value = value.accessWith(createReadVarargs(evaluatedIndex)); - } - values.put(value.getName(), value.makeOriginal()); - evaluatedIndex++; - } - } - } - - public static LocalContext load(NodeGenFactory factory) { - return load(factory, factory.createSpecializationNodeSignature(factory.node.getSignatureSize()), factory.varArgsThreshold); - } - - public LocalContext copy() { - LocalContext copy = new LocalContext(factory); - copy.values.putAll(values); - return copy; - } - - private static String fieldValueName(NodeFieldData field) { - return field.getName() + "Value"; - } - - @SuppressWarnings("static-method") - public LocalVariable createValue(NodeExecutionData execution, TypeMirror type) { - return new LocalVariable(type, valueName(execution), null, null); - } - - public LocalVariable createShortCircuitValue(NodeExecutionData execution) { - return new LocalVariable(factory.getType(boolean.class), shortCircuitName(execution), null, null); - } - - private static String valueName(NodeExecutionData execution) { - return execution.getName() + "Value"; - } - - private static String shortCircuitName(NodeExecutionData execution) { - return "has" + ElementUtils.firstLetterUpperCase(valueName(execution)); - } - - public void set(String id, LocalVariable var) { - values.put(id, var); - } - - public LocalVariable get(String id) { - return values.get(id); - } - - public LocalVariable get(Parameter parameter, int signatureIndex) { - LocalVariable var = get(parameter.getLocalName()); - if (var == null && parameter.getSpecification().isSignature()) { - // lookup by signature index for executeWith - List childExecutions = factory.node.getChildExecutions(); - if (signatureIndex < childExecutions.size() && signatureIndex >= 0) { - NodeExecutionData execution = childExecutions.get(signatureIndex); - var = getValue(execution); - } - } - return var; - } - - public LocalVariable getValue(NodeExecutionData execution) { - return get(valueName(execution)); - } - - public LocalVariable getValue(int signatureIndex) { - List childExecutions = factory.node.getChildExecutions(); - if (signatureIndex < childExecutions.size()) { - return getValue(childExecutions.get(signatureIndex)); - } else { - return null; - } - } - - public void removeValue(String id) { - values.remove(id); - } - - public void setValue(NodeExecutionData execution, LocalVariable var) { - values.put(valueName(execution), var); - } - - public void setShortCircuitValue(NodeExecutionData execution, LocalVariable var) { - if (var == null) { - return; - } - values.put(shortCircuitName(execution), var); - } - - private boolean needsVarargs(boolean requireLoaded, int varArgsThreshold) { - int size = 0; - for (NodeExecutionData execution : factory.node.getChildExecutions()) { - if (requireLoaded && getValue(execution) == null) { - continue; - } - if (execution.isShortCircuit()) { - size += 2; - } else { - size++; - } - } - return size >= varArgsThreshold; - } - - private static CodeTree createReadVarargs(int i) { - return CodeTreeBuilder.createBuilder().string("args_[").string(String.valueOf(i)).string("]").build(); - } - - public void addReferencesTo(CodeTreeBuilder builder, String... optionalNames) { - for (String var : optionalNames) { - LocalVariable local = values.get(var); - if (local == null) { - builder.nullLiteral(); - } else { - builder.tree(local.createReference()); - } - } - - List executions = factory.node.getChildExecutions(); - for (NodeExecutionData execution : executions) { - if (execution.isShortCircuit()) { - LocalVariable shortCircuitVar = getShortCircuit(execution); - if (shortCircuitVar != null) { - builder.tree(shortCircuitVar.createReference()); - } - } - LocalVariable var = getValue(execution); - if (var != null) { - builder.startGroup(); - if (executions.size() == 1 && ElementUtils.typeEquals(var.getTypeMirror(), factory.getType(Object[].class))) { - // if the current type is Object[] do not use varargs for a single argument - builder.string("(Object) "); - } - builder.tree(var.createReference()); - builder.end(); - } - } - } - - public void addParametersTo(CodeExecutableElement method, int varArgsThreshold, String... optionalNames) { - for (String var : optionalNames) { - LocalVariable local = values.get(var); - if (local != null) { - method.addParameter(local.createParameter()); - } - } - if (needsVarargs(true, varArgsThreshold)) { - method.addParameter(new CodeVariableElement(factory.getType(Object[].class), "args_")); - method.setVarArgs(true); - } else { - for (NodeExecutionData execution : factory.node.getChildExecutions()) { - if (execution.isShortCircuit()) { - LocalVariable shortCircuitVar = getShortCircuit(execution); - if (shortCircuitVar != null) { - method.addParameter(shortCircuitVar.createParameter()); - } - } - - LocalVariable var = getValue(execution); - if (var != null) { - method.addParameter(var.createParameter()); - } - } - } - } - - private LocalVariable getShortCircuit(NodeExecutionData execution) { - return values.get(shortCircuitName(execution)); - } - - @Override - public String toString() { - return "LocalContext [values=" + values + "]"; - } - - } - - public static final class LocalVariable { - - private final TypeMirror typeMirror; - private final CodeTree accessorTree; - private final String name; - private final LocalVariable previous; - - public static LocalVariable fromParameter(Parameter parameter) { - NodeExecutionData execution = parameter.getSpecification().getExecution(); - String name = null; - if (execution == null) { - name = parameter.getLocalName(); - } else { - name = createName(execution); - } - return new LocalVariable(parameter.getType(), name, null, null); - } - - private LocalVariable(TypeMirror typeMirror, String name, CodeTree accessorTree, LocalVariable previous) { - Objects.requireNonNull(typeMirror); - this.typeMirror = typeMirror; - this.accessorTree = accessorTree; - this.name = name; - this.previous = previous; - } - - public String getShortCircuitName() { - return "has" + ElementUtils.firstLetterUpperCase(getName()); - } - - public String getName() { - return name; - } - - private static String createNextName(String name) { - return name + "_"; - } - - private static String createName(NodeExecutionData execution) { - if (execution == null) { - return ""; - } - return execution.getName() + "Value"; - } - - public TypeMirror getTypeMirror() { - return typeMirror; - } - - public CodeVariableElement createParameter() { - return new CodeVariableElement(getTypeMirror(), getName()); - } - - public CodeTree createDeclaration(CodeTree init) { - return CodeTreeBuilder.createBuilder().declaration(getTypeMirror(), getName(), init).build(); - } - - public CodeTree createReference() { - if (accessorTree != null) { - return accessorTree; - } else { - return CodeTreeBuilder.singleString(getName()); - } - } - - public LocalVariable newType(TypeMirror newType) { - return new LocalVariable(newType, name, accessorTree, this); - } - - public LocalVariable accessWith(CodeTree tree) { - return new LocalVariable(typeMirror, name, tree, this); - } - - public LocalVariable nextName() { - return new LocalVariable(typeMirror, createNextName(name), accessorTree, this); - } - - public LocalVariable makeOriginal() { - return new LocalVariable(typeMirror, name, accessorTree, null); - } - - public LocalVariable original() { - LocalVariable variable = this; - while (variable.previous != null) { - variable = variable.previous; - } - return variable; - } - - public LocalVariable makeGeneric(ProcessorContext context) { - return newType(context.getType(Object.class)); - } - - @Override - public String toString() { - return "Local[type = " + getTypeMirror() + ", name = " + name + ", accessWith = " + accessorTree + "]"; - } - - } - - private abstract class SpecializationBody { - - private final boolean fastPath; - private final boolean needsCastedValues; - - public SpecializationBody(boolean fastPath, boolean needsCastedValues) { - this.fastPath = fastPath; - this.needsCastedValues = needsCastedValues; - } - - public final boolean isFastPath() { - return fastPath; - } - - public final boolean needsCastedValues() { - return needsCastedValues; - } - - public abstract CodeTree createBody(SpecializationData specialization, LocalContext currentValues); - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.generator.GeneratorUtils.*; -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class TypeSystemCodeGenerator extends CodeTypeElementFactory { - - private static final String LOCAL_VALUE = "value"; - - public static CodeTree cast(TypeSystemData typeSystem, TypeMirror type, String content) { - return cast(typeSystem, type, CodeTreeBuilder.singleString(content)); - } - - public static CodeTree implicitType(TypeSystemData typeSystem, TypeMirror type, CodeTree value) { - if (ElementUtils.isObject(type)) { - return value; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startStaticCall(createTypeSystemGen(typeSystem), getImplicitClass(typeSystem, type)).tree(value); - builder.end(); - return builder.build(); - } - - public static CodeTree invokeImplicitCast(TypeSystemData typeSystem, ImplicitCastData cast, CodeTree expression) { - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startStaticCall(createTypeSystemGen(typeSystem), cast.getMethodName()).tree(expression); - builder.end(); - return builder.build(); - } - - public static CodeTree implicitCheck(TypeSystemData typeSystem, TypeMirror type, CodeTree value, String typeHint) { - return callImplictMethod(typeSystem, type, isImplicitTypeMethodName(typeSystem, type), value, typeHint); - } - - public static CodeTree implicitExpect(TypeSystemData typeSystem, TypeMirror type, CodeTree value, String typeHint) { - return callImplictMethod(typeSystem, type, expectImplicitTypeMethodName(typeSystem, type), value, typeHint); - } - - public static CodeTree implicitCast(TypeSystemData typeSystem, TypeMirror type, CodeTree value, String typeHint) { - return callImplictMethod(typeSystem, type, asImplicitTypeMethodName(typeSystem, type), value, typeHint); - } - - private static CodeTree callImplictMethod(TypeSystemData typeSystem, TypeMirror type, String methodName, CodeTree value, String typeHint) { - if (ElementUtils.isObject(type)) { - return value; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - builder.startStaticCall(createTypeSystemGen(typeSystem), methodName).tree(value); - if (typeHint != null) { - builder.string(typeHint); - } - builder.end(); - return builder.build(); - } - - public static CodeTree cast(TypeSystemData typeSystem, TypeMirror type, CodeTree content) { - if (ElementUtils.isObject(type)) { - return content; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - TypeCastData cast = typeSystem.getCast(type); - if (cast == null) { - builder.cast(ElementUtils.fillInGenericWildcards(type), content); - } else { - builder.startStaticCall(typeSystem.getTemplateType().asType(), cast.getMethodName()).tree(content).end(); - } - return builder.build(); - } - - public static CodeTree expect(TypeSystemData typeSystem, TypeMirror type, CodeTree content) { - if (ElementUtils.isObject(type) || ElementUtils.isVoid(type)) { - return content; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - if (typeSystem.hasType(type)) { - builder.startStaticCall(createTypeSystemGen(typeSystem), expectTypeMethodName(typeSystem, type)).tree(content).end(); - } else { - builder.startCall(expectTypeMethodName(typeSystem, type)).tree(content).end(); - } - - return builder.build(); - } - - public static CodeExecutableElement createExpectMethod(Modifier visibility, TypeSystemData typeSystem, TypeMirror sourceTypeOriginal, TypeMirror expectedTypeOriginal) { - TypeMirror expectedType = ElementUtils.fillInGenericWildcards(expectedTypeOriginal); - TypeMirror sourceType = ElementUtils.fillInGenericWildcards(sourceTypeOriginal); - if (ElementUtils.isObject(expectedType) || ElementUtils.isVoid(expectedType)) { - return null; - } - - CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), expectedType, TypeSystemCodeGenerator.expectTypeMethodName(typeSystem, expectedType)); - method.setVisibility(visibility); - method.addParameter(new CodeVariableElement(sourceType, LOCAL_VALUE)); - method.addThrownType(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException()); - - CodeTreeBuilder body = method.createBuilder(); - body.startIf().tree(check(typeSystem, expectedType, LOCAL_VALUE)).end().startBlock(); - body.startReturn().tree(cast(typeSystem, expectedType, LOCAL_VALUE)).end(); - body.end(); - body.startThrow().startNew(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); - return method; - } - - public static CodeTree expect(TypeSystemData typeSystem, TypeMirror sourceType, TypeMirror targetType, CodeTree content) { - if (sourceType != null && !ElementUtils.needsCastTo(sourceType, targetType)) { - return content; - } else { - return expect(typeSystem, targetType, content); - } - } - - public static CodeTypeMirror createTypeSystemGen(TypeSystemData typeSystem) { - return new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()), typeName(typeSystem)); - } - - public static CodeTree check(TypeSystemData typeSystem, TypeMirror type, String content) { - return check(typeSystem, type, CodeTreeBuilder.singleString(content)); - } - - public static CodeTree check(TypeSystemData typeSystem, TypeMirror type, CodeTree content) { - if (ElementUtils.isObject(type)) { - return content; - } - CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); - - TypeCheckData check = typeSystem.getCheck(type); - if (check == null) { - builder.instanceOf(content, ElementUtils.boxType(typeSystem.getContext(), type)); - } else { - builder.startStaticCall(typeSystem.getTemplateType().asType(), check.getMethodName()).tree(content).end(); - } - return builder.build(); - } - - public static String isTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "is" + getTypeId(typeSystem, type); - } - - private static String getTypeId(TypeSystemData typeSystem, TypeMirror type) { - return ElementUtils.getTypeId(typeSystem.boxType(type)); - } - - static String isImplicitTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "isImplicit" + getTypeId(typeSystem, type); - } - - public static String asTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "as" + getTypeId(typeSystem, type); - } - - static String asImplicitTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "asImplicit" + getTypeId(typeSystem, type); - } - - static String expectImplicitTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "expectImplicit" + getTypeId(typeSystem, type); - } - - static String getImplicitClass(TypeSystemData typeSystem, TypeMirror type) { - return "getImplicit" + getTypeId(typeSystem, type) + "Class"; - } - - public static String expectTypeMethodName(TypeSystemData typeSystem, TypeMirror type) { - return "expect" + getTypeId(typeSystem, type); - } - - static String typeName(TypeSystemData typeSystem) { - String name = getSimpleName(typeSystem.getTemplateType()); - return name + "Gen"; - } - - static String singletonName(TypeSystemData type) { - return createConstantName(getSimpleName(type.getTemplateType().asType())); - } - - @Override - public CodeTypeElement create(ProcessorContext context, TypeSystemData typeSystem) { - CodeTypeElement clazz = new TypeClassFactory(context, typeSystem).create(); - - if (typeSystem.getOptions().implicitCastOptimization().isMergeCasts()) { - for (TypeMirror type : typeSystem.lookupTargetTypes()) { - clazz.add(new ImplicitCastNodeFactory(context, typeSystem, type).create()); - } - } - return clazz; - } - - private static class TypeClassFactory { - - private final ProcessorContext context; - private final TypeSystemData typeSystem; - - public TypeClassFactory(ProcessorContext context, TypeSystemData typeSystem) { - this.context = context; - this.typeSystem = typeSystem; - } - - public CodeTypeElement create() { - String name = typeName(typeSystem); - CodeTypeElement clazz = GeneratorUtils.createClass(typeSystem, null, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType()); - - clazz.add(GeneratorUtils.createConstructorUsingFields(modifiers(PROTECTED), clazz)); - CodeVariableElement singleton = createSingleton(clazz); - clazz.add(singleton); - - for (TypeMirror type : typeSystem.getLegacyTypes()) { - if (ElementUtils.isVoid(type) || ElementUtils.isObject(type)) { - continue; - } - - clazz.addOptional(createIsTypeMethod(type)); - clazz.addOptional(createAsTypeMethod(type)); - clazz.addOptional(createExpectTypeMethod(type, context.getType(Object.class))); - - } - - List lookupTargetTypes = typeSystem.lookupTargetTypes(); - for (TypeMirror type : lookupTargetTypes) { - clazz.add(createAsImplicitTypeMethod(type, false)); - if (typeSystem.getOptions().implicitCastOptimization().isNone()) { - clazz.add(createExpectImplicitTypeMethod(type, false)); - } - clazz.add(createIsImplicitTypeMethod(type, false)); - - if (typeSystem.getOptions().implicitCastOptimization().isDuplicateTail()) { - clazz.add(createAsImplicitTypeMethod(type, true)); - clazz.add(createExpectImplicitTypeMethod(type, true)); - clazz.add(createIsImplicitTypeMethod(type, true)); - clazz.add(createGetImplicitClass(type)); - } - } - return clazz; - } - - private CodeVariableElement createSingleton(CodeTypeElement clazz) { - CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(typeSystem)); - field.createInitBuilder().startNew(clazz.asType()).end(); - - CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror((DeclaredType) context.getType(Deprecated.class)); - field.getAnnotationMirrors().add(annotationMirror); - - return field; - } - - private CodeExecutableElement createIsImplicitTypeMethod(TypeMirror type, boolean typed) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(typeSystem, type)); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - if (typed) { - method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint")); - } - CodeTreeBuilder builder = method.createBuilder(); - - List sourceTypes = typeSystem.lookupSourceTypes(type); - - builder.startReturn(); - String sep = ""; - for (TypeMirror sourceType : sourceTypes) { - builder.string(sep); - if (typed) { - builder.string("(typeHint == ").typeLiteral(sourceType).string(" && "); - } - builder.tree(check(typeSystem, sourceType, LOCAL_VALUE)); - if (typed) { - builder.string(")"); - } - if (sourceTypes.lastIndexOf(sourceType) != sourceTypes.size() - 1) { - builder.newLine(); - } - if (sep.equals("")) { - builder.startIndention(); - } - sep = " || "; - } - builder.end(); - builder.end(); - return method; - } - - private CodeExecutableElement createAsImplicitTypeMethod(TypeMirror type, boolean useTypeHint) { - String name = asImplicitTypeMethodName(typeSystem, type); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type, name); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - if (useTypeHint) { - method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint")); - } - - List sourceTypes = typeSystem.lookupSourceTypes(type); - - CodeTreeBuilder builder = method.createBuilder(); - boolean elseIf = false; - for (TypeMirror sourceType : sourceTypes) { - elseIf = builder.startIf(elseIf); - if (useTypeHint) { - builder.string("typeHint == ").typeLiteral(sourceType); - } else { - builder.tree(check(typeSystem, sourceType, LOCAL_VALUE)); - } - - builder.end().startBlock(); - - builder.startReturn(); - ImplicitCastData cast = typeSystem.lookupCast(sourceType, type); - if (cast != null) { - builder.startCall(cast.getMethodName()); - } - builder.tree(cast(typeSystem, sourceType, LOCAL_VALUE)).end(); - if (cast != null) { - builder.end(); - } - builder.end(); - builder.end(); - } - - builder.startElseBlock(); - builder.tree(createTransferToInterpreterAndInvalidate()); - builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); - builder.end(); - return method; - } - - private CodeExecutableElement createExpectImplicitTypeMethod(TypeMirror type, boolean useTypeHint) { - String name = expectImplicitTypeMethodName(typeSystem, type); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type, name); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - if (useTypeHint) { - method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint")); - } - method.getThrownTypes().add(context.getType(UnexpectedResultException.class)); - - List sourceTypes = typeSystem.lookupSourceTypes(type); - - CodeTreeBuilder builder = method.createBuilder(); - boolean elseIf = false; - for (TypeMirror sourceType : sourceTypes) { - elseIf = builder.startIf(elseIf); - if (useTypeHint) { - builder.string("typeHint == ").typeLiteral(sourceType); - builder.string(" && "); - } - builder.tree(check(typeSystem, sourceType, LOCAL_VALUE)); - - builder.end().startBlock(); - - builder.startReturn(); - ImplicitCastData cast = typeSystem.lookupCast(sourceType, type); - if (cast != null) { - builder.startCall(cast.getMethodName()); - } - builder.tree(cast(typeSystem, sourceType, LOCAL_VALUE)).end(); - if (cast != null) { - builder.end(); - } - builder.end(); - builder.end(); - } - - builder.startElseBlock(); - builder.startThrow().startNew(context.getType(UnexpectedResultException.class)).string(LOCAL_VALUE).end().end(); - builder.end(); - return method; - } - - private CodeExecutableElement createGetImplicitClass(TypeMirror type) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(typeSystem, type)); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - - List sourceTypes = typeSystem.lookupSourceTypes(type); - CodeTreeBuilder builder = method.createBuilder(); - boolean elseIf = false; - for (TypeMirror sourceType : sourceTypes) { - elseIf = builder.startIf(elseIf); - builder.tree(check(typeSystem, sourceType, LOCAL_VALUE)).end(); - builder.end().startBlock(); - builder.startReturn().typeLiteral(sourceType).end(); - builder.end(); - } - - builder.startElseIf().string(LOCAL_VALUE).string(" == ").nullLiteral().end(); - builder.startBlock(); - builder.startReturn().typeLiteral(context.getType(Object.class)).end(); - builder.end(); - - builder.startElseBlock(); - builder.tree(createTransferToInterpreterAndInvalidate()); - builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); - builder.end(); - - return method; - } - - private CodeExecutableElement createIsTypeMethod(TypeMirror type) { - if (typeSystem.getCheck(type) != null) { - return null; - } - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(typeSystem, type)); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - - CodeTreeBuilder body = method.createBuilder(); - body.startReturn().tree(check(typeSystem, type, LOCAL_VALUE)).end(); - - return method; - } - - private CodeExecutableElement createAsTypeMethod(TypeMirror type) { - if (typeSystem.getCast(type) != null) { - return null; - } - - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type, TypeSystemCodeGenerator.asTypeMethodName(typeSystem, type)); - method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - - CodeTreeBuilder body = method.createBuilder(); - String assertMessage = typeName(typeSystem) + "." + asTypeMethodName(typeSystem, type) + ": " + ElementUtils.getSimpleName(type) + " expected"; - body.startAssert().tree(check(typeSystem, type, LOCAL_VALUE)).string(" : ").doubleQuote(assertMessage).end(); - body.startReturn().tree(cast(typeSystem, type, LOCAL_VALUE)).end(); - - return method; - } - - private CodeExecutableElement createExpectTypeMethod(TypeMirror expectedType, TypeMirror sourceType) { - return createExpectMethod(Modifier.PUBLIC, typeSystem, sourceType, expectedType); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1256 +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.dsl.processor.java; - -import java.io.*; -import java.lang.annotation.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; - -/** - * THIS IS NOT PUBLIC API. - */ -public class ElementUtils { - - public static TypeMirror getType(ProcessingEnvironment processingEnv, Class element) { - if (element.isArray()) { - return processingEnv.getTypeUtils().getArrayType(getType(processingEnv, element.getComponentType())); - } - if (element.isPrimitive()) { - if (element == void.class) { - return processingEnv.getTypeUtils().getNoType(TypeKind.VOID); - } - TypeKind typeKind; - if (element == boolean.class) { - typeKind = TypeKind.BOOLEAN; - } else if (element == byte.class) { - typeKind = TypeKind.BYTE; - } else if (element == short.class) { - typeKind = TypeKind.SHORT; - } else if (element == char.class) { - typeKind = TypeKind.CHAR; - } else if (element == int.class) { - typeKind = TypeKind.INT; - } else if (element == long.class) { - typeKind = TypeKind.LONG; - } else if (element == float.class) { - typeKind = TypeKind.FLOAT; - } else if (element == double.class) { - typeKind = TypeKind.DOUBLE; - } else { - assert false; - return null; - } - return processingEnv.getTypeUtils().getPrimitiveType(typeKind); - } else { - TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(element.getCanonicalName()); - if (typeElement == null) { - return null; - } - return typeElement.asType(); - } - } - - public static ExecutableElement findExecutableElement(DeclaredType type, String name) { - List elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); - for (ExecutableElement executableElement : elements) { - if (executableElement.getSimpleName().toString().equals(name)) { - return executableElement; - } - } - return null; - } - - public static boolean needsCastTo(TypeMirror sourceType, TypeMirror targetType) { - if (typeEquals(sourceType, targetType)) { - return false; - } else if (isObject(targetType)) { - return false; - } else if (isVoid(targetType)) { - return false; - } else if (isAssignable(sourceType, targetType)) { - return false; - } - return true; - } - - public static String createReferenceName(ExecutableElement method) { - StringBuilder b = new StringBuilder(); - - b.append(method.getSimpleName().toString()); - b.append("("); - - String sep = ""; - for (VariableElement parameter : method.getParameters()) { - b.append(sep); - b.append(ElementUtils.getSimpleName(parameter.asType())); - sep = ", "; - } - - b.append(")"); - return b.toString(); - } - - public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) { - if (primitiveType == null) { - return null; - } - TypeMirror boxedType = primitiveType; - if (boxedType.getKind().isPrimitive()) { - boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType(); - } - return boxedType; - } - - public static DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { - return new DeclaredCodeTypeMirror(typeElem, Arrays.asList(typeArgs)); - } - - public static List collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element, - Class annotationClass) { - List result = new ArrayList<>(); - if (markerAnnotation != null) { - result.addAll(ElementUtils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName)); - } - AnnotationMirror explicit = ElementUtils.findAnnotationMirror(context.getEnvironment(), element, annotationClass); - if (explicit != null) { - result.add(explicit); - } - return result; - } - - public static TypeMirror getCommonSuperType(ProcessorContext context, Collection types) { - if (types.isEmpty()) { - return context.getType(Object.class); - } - Iterator typesIterator = types.iterator(); - TypeMirror prev = typesIterator.next(); - while (typesIterator.hasNext()) { - prev = getCommonSuperType(context, prev, typesIterator.next()); - } - return prev; - } - - private static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) { - if (typeEquals(type1, type2)) { - return type1; - } - if (isVoid(type1)) { - return type2; - } else if (isVoid(type2)) { - return type1; - } - if (isObject(type1)) { - return type1; - } else if (isObject(type2)) { - return type2; - } - - if (isPrimitive(type1) || isPrimitive(type2)) { - return context.getType(Object.class); - } - - if (isSubtype(type1, type2)) { - return type2; - } else if (isSubtype(type2, type1)) { - return type1; - } - - TypeElement element1 = fromTypeMirror(type1); - TypeElement element2 = fromTypeMirror(type2); - - if (element1 == null || element2 == null) { - return context.getType(Object.class); - } - - List element1Types = getSuperTypes(element1); - List element2Types = getSuperTypes(element2); - - for (TypeElement superType1 : element1Types) { - for (TypeElement superType2 : element2Types) { - if (typeEquals(superType1.asType(), superType2.asType())) { - return superType2.asType(); - } - } - } - - return context.getType(Object.class); - } - - public static String getReadableSignature(ExecutableElement method) { - StringBuilder builder = new StringBuilder(); - builder.append(method.getSimpleName().toString()); - builder.append("("); - String sep = ""; - for (VariableElement var : method.getParameters()) { - builder.append(sep); - builder.append(getSimpleName(var.asType())); - sep = ", "; - } - builder.append(")"); - return builder.toString(); - } - - public static boolean hasError(TypeMirror mirror) { - switch (mirror.getKind()) { - case BOOLEAN: - case BYTE: - case CHAR: - case DOUBLE: - case FLOAT: - case INT: - case SHORT: - case LONG: - case DECLARED: - case VOID: - case TYPEVAR: - return false; - case ARRAY: - return hasError(((ArrayType) mirror).getComponentType()); - case ERROR: - return true; - default: - throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); - } - } - - public static boolean isSubtypeBoxed(ProcessorContext context, TypeMirror from, TypeMirror to) { - return isSubtype(boxType(context, from), boxType(context, to)); - } - - public static boolean isSubtype(TypeMirror type1, TypeMirror type2) { - if (type1 instanceof CodeTypeMirror || type2 instanceof CodeTypeMirror) { - throw new UnsupportedOperationException(); - } - return ProcessorContext.getInstance().getEnvironment().getTypeUtils().isSubtype(type1, type2); - } - - public static boolean isAssignable(TypeMirror from, TypeMirror to) { - if (typeEquals(from, to)) { - return true; - } else if (isVoid(to)) { - return true; - } else if (isObject(to)) { - return true; - } - ProcessorContext context = ProcessorContext.getInstance(); - if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) { - return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to)); - } else { - return isAssignableImpl(from, to); - } - } - - private static boolean isAssignableImpl(TypeMirror from, TypeMirror to) { - // JLS 5.1.1 identity conversion - if (ElementUtils.typeEquals(from, to)) { - return true; - } - - if (isObject(to)) { - return true; - } - - // JLS 5.1.2 widening primitives - if (ElementUtils.isPrimitive(from) && ElementUtils.isPrimitive(to)) { - TypeKind fromKind = from.getKind(); - TypeKind toKind = to.getKind(); - switch (fromKind) { - case BYTE: - switch (toKind) { - case SHORT: - case INT: - case LONG: - case FLOAT: - case DOUBLE: - return true; - } - break; - case SHORT: - switch (toKind) { - case INT: - case LONG: - case FLOAT: - case DOUBLE: - return true; - } - break; - case CHAR: - switch (toKind) { - case INT: - case LONG: - case FLOAT: - case DOUBLE: - return true; - } - break; - case INT: - switch (toKind) { - case LONG: - case FLOAT: - case DOUBLE: - return true; - } - break; - case LONG: - switch (toKind) { - case FLOAT: - case DOUBLE: - return true; - } - break; - case FLOAT: - switch (toKind) { - case DOUBLE: - return true; - } - break; - - } - return false; - } else if (ElementUtils.isPrimitive(from) || ElementUtils.isPrimitive(to)) { - return false; - } - - if (from instanceof ArrayType && to instanceof ArrayType) { - return isAssignable(((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType()); - } - - if (from instanceof ArrayType || to instanceof ArrayType) { - return false; - } - - TypeElement fromType = ElementUtils.fromTypeMirror(from); - TypeElement toType = ElementUtils.fromTypeMirror(to); - if (fromType == null || toType == null) { - return false; - } - // JLS 5.1.6 narrowing reference conversion - - List superTypes = ElementUtils.getSuperTypes(fromType); - for (TypeElement superType : superTypes) { - if (ElementUtils.typeEquals(superType.asType(), to)) { - return true; - } - } - - // TODO more spec - return false; - } - - public static Set modifiers(Modifier... modifier) { - return new LinkedHashSet<>(Arrays.asList(modifier)); - } - - public static String getTypeId(TypeMirror mirror) { - switch (mirror.getKind()) { - case BOOLEAN: - return "Boolean"; - case BYTE: - return "Byte"; - case CHAR: - return "Char"; - case DOUBLE: - return "Double"; - case FLOAT: - return "Float"; - case SHORT: - return "Short"; - case INT: - return "Int"; - case LONG: - return "Long"; - case DECLARED: - return fixECJBinaryNameIssue(((DeclaredType) mirror).asElement().getSimpleName().toString()); - case ARRAY: - return getTypeId(((ArrayType) mirror).getComponentType()) + "Array"; - case VOID: - return "Void"; - case NULL: - return "Null"; - case WILDCARD: - StringBuilder b = new StringBuilder(); - WildcardType type = (WildcardType) mirror; - if (type.getExtendsBound() != null) { - b.append("Extends").append(getTypeId(type.getExtendsBound())); - } else if (type.getSuperBound() != null) { - b.append("Super").append(getTypeId(type.getExtendsBound())); - } - return b.toString(); - case TYPEVAR: - return "Any"; - case ERROR: - throw new CompileErrorException("Type error " + mirror); - default: - throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); - } - } - - public static String getSimpleName(TypeElement element) { - return getSimpleName(element.asType()); - } - - public static String getSimpleName(TypeMirror mirror) { - switch (mirror.getKind()) { - case BOOLEAN: - return "boolean"; - case BYTE: - return "byte"; - case CHAR: - return "char"; - case DOUBLE: - return "double"; - case FLOAT: - return "float"; - case SHORT: - return "short"; - case INT: - return "int"; - case LONG: - return "long"; - case DECLARED: - return getDeclaredName((DeclaredType) mirror, true); - case ARRAY: - return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]"; - case VOID: - return "void"; - case NULL: - return "null"; - case WILDCARD: - return getWildcardName((WildcardType) mirror); - case TYPEVAR: - return "?"; - case ERROR: - throw new CompileErrorException("Type error " + mirror); - default: - throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); - } - } - - private static String getWildcardName(WildcardType type) { - StringBuilder b = new StringBuilder(); - if (type.getExtendsBound() != null) { - b.append("? extends ").append(getSimpleName(type.getExtendsBound())); - } else if (type.getSuperBound() != null) { - b.append("? super ").append(getSimpleName(type.getExtendsBound())); - } - return b.toString(); - } - - public static String getDeclaredName(DeclaredType element, boolean includeTypeVariables) { - String simpleName = fixECJBinaryNameIssue(element.asElement().getSimpleName().toString()); - - if (!includeTypeVariables || element.getTypeArguments().size() == 0) { - return simpleName; - } - - StringBuilder b = new StringBuilder(simpleName); - b.append("<"); - if (element.getTypeArguments().size() > 0) { - for (int i = 0; i < element.getTypeArguments().size(); i++) { - b.append(getSimpleName(element.getTypeArguments().get(i))); - if (i < element.getTypeArguments().size() - 1) { - b.append(", "); - } - } - } - b.append(">"); - return b.toString(); - } - - public static String fixECJBinaryNameIssue(String name) { - if (name.contains("$")) { - int lastIndex = name.lastIndexOf('$'); - return name.substring(lastIndex + 1, name.length()); - } - return name; - } - - public static String getQualifiedName(TypeElement element) { - String qualifiedName = element.getQualifiedName().toString(); - if (qualifiedName.contains("$")) { - /* - * If a class gets loaded in its binary form by the ECJ compiler it fails to produce the - * proper canonical class name. It leaves the $ in the qualified name of the class. So - * one instance of a TypeElement may be loaded in binary and one in source form. The - * current type comparison in #typeEquals compares by the qualified name so the - * qualified name must match. This is basically a hack to fix the returned qualified - * name of eclipse. - */ - qualifiedName = qualifiedName.replace('$', '.'); - } - return qualifiedName; - } - - public static String getQualifiedName(TypeMirror mirror) { - switch (mirror.getKind()) { - case BOOLEAN: - return "boolean"; - case BYTE: - return "byte"; - case CHAR: - return "char"; - case DOUBLE: - return "double"; - case SHORT: - return "short"; - case FLOAT: - return "float"; - case INT: - return "int"; - case LONG: - return "long"; - case DECLARED: - return getQualifiedName(fromTypeMirror(mirror)); - case ARRAY: - return getQualifiedName(((ArrayType) mirror).getComponentType()); - case VOID: - return "void"; - case NULL: - return "null"; - case TYPEVAR: - return getSimpleName(mirror); - case ERROR: - throw new CompileErrorException("Type error " + mirror); - case EXECUTABLE: - return ((ExecutableType) mirror).toString(); - case NONE: - return "$none"; - default: - throw new RuntimeException("Unknown type specified " + mirror + " mirror: " + mirror); - } - } - - public static boolean isVoid(TypeMirror mirror) { - return mirror != null && mirror.getKind() == TypeKind.VOID; - } - - public static boolean isPrimitive(TypeMirror mirror) { - return mirror != null && mirror.getKind().isPrimitive(); - } - - public static List getQualifiedSuperTypeNames(TypeElement element) { - List types = getSuperTypes(element); - List qualifiedNames = new ArrayList<>(); - for (TypeElement type : types) { - qualifiedNames.add(getQualifiedName(type)); - } - return qualifiedNames; - } - - public static List getDeclaredTypes(TypeElement element) { - return ElementFilter.typesIn(element.getEnclosedElements()); - } - - public static boolean isEnclosedIn(Element enclosedIn, Element element) { - if (element == null) { - return false; - } else if (typeEquals(enclosedIn.asType(), element.asType())) { - return true; - } else { - return isEnclosedIn(enclosedIn, element.getEnclosingElement()); - } - } - - public static TypeElement findRootEnclosingType(Element element) { - List elements = getElementHierarchy(element); - - for (int i = elements.size() - 1; i >= 0; i--) { - if (elements.get(i).getKind().isClass()) { - return (TypeElement) elements.get(i); - } - } - - return null; - } - - public static List getElementHierarchy(Element e) { - List elements = new ArrayList<>(); - elements.add(e); - - Element enclosing = e.getEnclosingElement(); - while (enclosing != null && enclosing.getKind() != ElementKind.PACKAGE) { - elements.add(enclosing); - enclosing = enclosing.getEnclosingElement(); - } - if (enclosing != null) { - elements.add(enclosing); - } - return elements; - } - - public static TypeElement findNearestEnclosingType(Element element) { - List elements = getElementHierarchy(element); - for (Element e : elements) { - if (e.getKind().isClass() || e.getKind().isInterface()) { - return (TypeElement) e; - } - } - return null; - } - - public static List getDirectSuperTypes(TypeElement element) { - List types = new ArrayList<>(); - TypeElement superElement = getSuperType(element); - if (superElement != null) { - types.add(superElement); - types.addAll(getDirectSuperTypes(superElement)); - } - - return types; - } - - /** - * Gets the element representing the {@linkplain TypeElement#getSuperclass() super class} of a - * given type element. - */ - public static TypeElement getSuperType(TypeElement element) { - if (element.getSuperclass() != null) { - return fromTypeMirror(element.getSuperclass()); - } - return null; - } - - public static List getSuperTypes(TypeElement element) { - List types = new ArrayList<>(); - List superTypes = null; - List superInterfaces = null; - TypeElement superElement = getSuperType(element); - if (superElement != null) { - types.add(superElement); - superTypes = getSuperTypes(superElement); - } - for (TypeMirror interfaceMirror : element.getInterfaces()) { - TypeElement interfaceElement = fromTypeMirror(interfaceMirror); - if (interfaceElement != null) { - types.add(interfaceElement); - if (superInterfaces == null) { - superInterfaces = getSuperTypes(interfaceElement); - } else { - superInterfaces.addAll(getSuperTypes(interfaceElement)); - } - } - } - - if (superTypes != null) { - types.addAll(superTypes); - } - - if (superInterfaces != null) { - types.addAll(superInterfaces); - } - - return types; - } - - public static String getPackageName(TypeElement element) { - return findPackageElement(element).getQualifiedName().toString(); - } - - public static String getEnclosedQualifiedName(DeclaredType mirror) { - Element e = ((TypeElement) mirror.asElement()).getEnclosingElement(); - if (e.getKind() == ElementKind.PACKAGE) { - return ((PackageElement) e).getQualifiedName().toString(); - } else if (e.getKind().isInterface() || e.getKind().isClass()) { - return getQualifiedName((TypeElement) e); - } else { - return null; - } - } - - public static String getPackageName(TypeMirror mirror) { - switch (mirror.getKind()) { - case BOOLEAN: - case BYTE: - case CHAR: - case DOUBLE: - case FLOAT: - case SHORT: - case INT: - case LONG: - case VOID: - case NULL: - case TYPEVAR: - return null; - case DECLARED: - PackageElement pack = findPackageElement(fromTypeMirror(mirror)); - if (pack == null) { - throw new IllegalArgumentException("No package element found for declared type " + getSimpleName(mirror)); - } - return pack.getQualifiedName().toString(); - case ARRAY: - return getSimpleName(((ArrayType) mirror).getComponentType()); - case EXECUTABLE: - return null; - default: - throw new RuntimeException("Unknown type specified " + mirror.getKind()); - } - } - - public static String createConstantName(String simpleName) { - // TODO use camel case to produce underscores. - return simpleName.toString().toUpperCase(); - } - - public static TypeElement fromTypeMirror(TypeMirror mirror) { - switch (mirror.getKind()) { - case DECLARED: - return (TypeElement) ((DeclaredType) mirror).asElement(); - case ARRAY: - return fromTypeMirror(((ArrayType) mirror).getComponentType()); - default: - return null; - } - } - - @SuppressWarnings("unchecked") - public static List getAnnotationValueList(Class expectedListType, AnnotationMirror mirror, String name) { - List values = getAnnotationValue(List.class, mirror, name); - List result = new ArrayList<>(); - - if (values != null) { - for (AnnotationValue value : values) { - T annotationValue = resolveAnnotationValue(expectedListType, value); - if (annotationValue != null) { - result.add(annotationValue); - } - } - } - return result; - } - - public static T getAnnotationValue(Class expectedType, AnnotationMirror mirror, String name) { - return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name)); - } - - @SuppressWarnings({"unchecked"}) - private static T resolveAnnotationValue(Class expectedType, AnnotationValue value) { - if (value == null) { - return null; - } - - Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null); - if (unboxedValue != null) { - if (expectedType == TypeMirror.class && unboxedValue instanceof String) { - return null; - } - if (!expectedType.isAssignableFrom(unboxedValue.getClass())) { - throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName()); - } - } - return (T) unboxedValue; - } - - public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) { - ExecutableElement valueMethod = null; - for (ExecutableElement method : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { - if (method.getSimpleName().toString().equals(name)) { - valueMethod = method; - break; - } - } - - if (valueMethod == null) { - return null; - } - - AnnotationValue value = mirror.getElementValues().get(valueMethod); - if (value == null) { - value = valueMethod.getDefaultValue(); - } - - return value; - } - - private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7 { - - @Override - public Object visitBoolean(boolean b, Void p) { - return Boolean.valueOf(b); - } - - @Override - public Object visitByte(byte b, Void p) { - return Byte.valueOf(b); - } - - @Override - public Object visitChar(char c, Void p) { - return c; - } - - @Override - public Object visitDouble(double d, Void p) { - return d; - } - - @Override - public Object visitFloat(float f, Void p) { - return f; - } - - @Override - public Object visitInt(int i, Void p) { - return i; - } - - @Override - public Object visitLong(long i, Void p) { - return i; - } - - @Override - public Object visitShort(short s, Void p) { - return s; - } - - @Override - public Object visitString(String s, Void p) { - return s; - } - - @Override - public Object visitType(TypeMirror t, Void p) { - return t; - } - - @Override - public Object visitEnumConstant(VariableElement c, Void p) { - return c; - } - - @Override - public Object visitAnnotation(AnnotationMirror a, Void p) { - return a; - } - - @Override - public Object visitArray(List vals, Void p) { - return vals; - } - - } - - public static String printException(Throwable e) { - StringWriter string = new StringWriter(); - PrintWriter writer = new PrintWriter(string); - e.printStackTrace(writer); - writer.flush(); - string.flush(); - return e.getMessage() + "\r\n" + string.toString(); - } - - public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, Class annotationClass) { - return findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), annotationClass); - } - - public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List mirrors, Class annotationClass) { - TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName()); - return findAnnotationMirror(mirrors, expectedAnnotationType.asType()); - } - - public static AnnotationMirror findAnnotationMirror(List mirrors, TypeElement expectedAnnotationType) { - return findAnnotationMirror(mirrors, expectedAnnotationType.asType()); - } - - public static AnnotationMirror findAnnotationMirror(List mirrors, TypeMirror expectedAnnotationType) { - for (AnnotationMirror mirror : mirrors) { - if (typeEquals(mirror.getAnnotationType(), expectedAnnotationType)) { - return mirror; - } - } - return null; - } - - public static PackageElement findPackageElement(Element type) { - List hierarchy = getElementHierarchy(type); - for (Element element : hierarchy) { - if (element.getKind() == ElementKind.PACKAGE) { - return (PackageElement) element; - } - } - return null; - } - - public static String firstLetterUpperCase(String name) { - if (name == null || name.isEmpty()) { - return name; - } - return Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length()); - } - - public static String firstLetterLowerCase(String name) { - if (name == null || name.isEmpty()) { - return name; - } - return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length()); - } - - private static ExecutableElement getDeclaredMethod(TypeElement element, String name, TypeMirror[] params) { - List methods = ElementFilter.methodsIn(element.getEnclosedElements()); - method: for (ExecutableElement method : methods) { - if (!method.getSimpleName().toString().equals(name)) { - continue; - } - if (method.getParameters().size() != params.length) { - continue; - } - for (int i = 0; i < params.length; i++) { - TypeMirror param1 = params[i]; - TypeMirror param2 = method.getParameters().get(i).asType(); - if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) { - if (!getQualifiedName(param1).equals(getQualifiedName(param2))) { - continue method; - } - } - } - return method; - } - return null; - } - - public static boolean isDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) { - return !getDeclaredMethodsInSuperTypes(element, name, params).isEmpty(); - } - - /** - * Gets the methods in the super type hierarchy (excluding interfaces) that are overridden by a - * method in a subtype. - * - * @param declaringElement the subtype element declaring the method - * @param name the name of the method - * @param params the signature of the method - */ - public static List getDeclaredMethodsInSuperTypes(TypeElement declaringElement, String name, TypeMirror... params) { - List superMethods = new ArrayList<>(); - List superElements = getSuperTypes(declaringElement); - - for (TypeElement superElement : superElements) { - ExecutableElement superMethod = getDeclaredMethod(superElement, name, params); - if (superMethod != null) { - superMethods.add(superMethod); - } - } - return superMethods; - } - - public static boolean typeEquals(TypeMirror type1, TypeMirror type2) { - if (type1 == type2) { - return true; - } else if (type1 == null || type2 == null) { - return false; - } else { - if (type1.getKind() == type2.getKind()) { - return getUniqueIdentifier(type1).equals(getUniqueIdentifier(type2)); - } else { - return false; - } - } - } - - public static boolean areTypesCompatible(TypeMirror type1, TypeMirror type2) { - if (typeEquals(type1, type2)) { - return true; - } else if (kindIsIntegral(type1.getKind())) { - return kindIsIntegral(type2.getKind()); - } else if (type1.getKind() == TypeKind.NULL) { - if (type2.getKind() == TypeKind.NULL) { - return false; - } - return true; - } else if (type2.getKind() == TypeKind.NULL) { - return true; - } else { - return false; - } - } - - private static boolean kindIsIntegral(TypeKind kind) { - return kind == TypeKind.BYTE || kind == TypeKind.SHORT || kind == TypeKind.INT || kind == TypeKind.LONG; - } - - public static List getUniqueIdentifiers(List typeMirror) { - List ids = new ArrayList<>(); - for (TypeMirror type : typeMirror) { - ids.add(getUniqueIdentifier(type)); - } - return ids; - } - - public static String getUniqueIdentifier(TypeMirror typeMirror) { - if (typeMirror.getKind() == TypeKind.ARRAY) { - return getUniqueIdentifier(((ArrayType) typeMirror).getComponentType()) + "[]"; - } else { - return getQualifiedName(typeMirror); - } - } - - public static int compareByTypeHierarchy(TypeMirror t1, TypeMirror t2) { - if (typeEquals(t1, t2)) { - return 0; - } - Set t1SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t1))); - if (t1SuperSet.contains(getQualifiedName(t2))) { - return -1; - } - - Set t2SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t2))); - if (t2SuperSet.contains(getQualifiedName(t1))) { - return 1; - } - return 0; - } - - public static boolean canThrowType(List thrownTypes, TypeMirror exceptionType) { - if (ElementUtils.containsType(thrownTypes, exceptionType)) { - return true; - } - - if (isRuntimeException(exceptionType)) { - return true; - } - - // search for any super types - for (TypeElement typeElement : getSuperTypes(fromTypeMirror(exceptionType))) { - if (ElementUtils.containsType(thrownTypes, typeElement.asType())) { - return true; - } - } - - return false; - } - - public static void setVisibility(Set modifiers, Modifier visibility) { - Modifier current = getVisibility(modifiers); - if (current != visibility) { - if (current != null) { - modifiers.remove(current); - } - if (visibility != null) { - modifiers.add(visibility); - } - } - } - - public static Modifier getVisibility(Set modifier) { - for (Modifier mod : modifier) { - if (mod == Modifier.PUBLIC || mod == Modifier.PRIVATE || mod == Modifier.PROTECTED) { - return mod; - } - } - return null; - } - - private static boolean isRuntimeException(TypeMirror type) { - Set typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type))); - return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || getQualifiedName(type).equals(RuntimeException.class.getCanonicalName()); - } - - private static boolean containsType(Collection collection, TypeMirror type) { - for (TypeMirror otherTypeMirror : collection) { - if (typeEquals(otherTypeMirror, type)) { - return true; - } - } - return false; - } - - public static boolean isTopLevelClass(TypeMirror importType) { - TypeElement type = fromTypeMirror(importType); - if (type != null && type.getEnclosingElement() != null) { - return !type.getEnclosingElement().getKind().isClass(); - } - return true; - } - - public static boolean isObject(TypeMirror actualType) { - return actualType.getKind() == TypeKind.DECLARED && getQualifiedName(actualType).equals("java.lang.Object"); - } - - public static TypeMirror fillInGenericWildcards(TypeMirror type) { - if (type.getKind() != TypeKind.DECLARED) { - return type; - } - DeclaredType declaredType = (DeclaredType) type; - TypeElement element = (TypeElement) declaredType.asElement(); - if (element == null) { - return type; - } - int typeParameters = element.getTypeParameters().size(); - if (typeParameters > 0 && declaredType.getTypeArguments().size() != typeParameters) { - return ProcessorContext.getInstance().getEnvironment().getTypeUtils().erasure(type); - } - return type; - } - - public static TypeMirror eraseGenericTypes(TypeMirror type) { - if (type.getKind() != TypeKind.DECLARED) { - return type; - } - DeclaredType declaredType = (DeclaredType) type; - if (declaredType.getTypeArguments().size() == 0) { - return type; - } - return new DeclaredCodeTypeMirror((TypeElement) declaredType.asElement()); - } - - public static boolean variableEquals(VariableElement var1, VariableElement var2) { - if (!var1.getSimpleName().equals(var2.getSimpleName())) { - return false; - } - if (!ElementUtils.typeEquals(var1.asType(), var2.asType())) { - return false; - } - if (!ElementUtils.elementEquals(var1.getEnclosingElement(), var2.getEnclosingElement())) { - return false; - } - return true; - } - - public static boolean executableEquals(ExecutableElement var1, ExecutableElement var2) { - if (!var1.getSimpleName().equals(var2.getSimpleName())) { - return false; - } - if (var1.getParameters().size() != var2.getParameters().size()) { - return false; - } - if (!ElementUtils.typeEquals(var1.asType(), var2.asType())) { - return false; - } - if (!ElementUtils.elementEquals(var1.getEnclosingElement(), var2.getEnclosingElement())) { - return false; - } - for (int i = 0; i < var1.getParameters().size(); i++) { - if (!typeEquals(var1.getParameters().get(i).asType(), var2.getParameters().get(i).asType())) { - return false; - } - } - return true; - } - - public static boolean elementEquals(Element element1, Element element2) { - if (element1.getKind() != element2.getKind()) { - return false; - } else if (element1 instanceof VariableElement) { - return variableEquals((VariableElement) element1, (VariableElement) element2); - } else if (element1 instanceof ExecutableElement) { - return executableEquals((ExecutableElement) element1, (ExecutableElement) element2); - } else if (element1 instanceof TypeElement) { - return typeEquals(element1.asType(), element2.asType()); - } else if (element1 instanceof PackageElement) { - return element1.getSimpleName().equals(element2.getSimpleName()); - } else { - throw new AssertionError("unsupported element type"); - } - } - - public static List sortTypes(List list, final boolean reverse) { - Collections.sort(list, new Comparator() { - public int compare(TypeMirror o1, TypeMirror o2) { - if (reverse) { - return compareType(o2, o1); - } else { - return compareType(o1, o2); - } - } - }); - return list; - } - - public static int compareType(TypeMirror signature1, TypeMirror signature2) { - if (signature1 == null) { - return 1; - } else if (signature2 == null) { - return -1; - } - - if (ElementUtils.typeEquals(signature1, signature2)) { - return 0; - } - - if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) { - TypeElement element1 = ElementUtils.fromTypeMirror(signature1); - TypeElement element2 = ElementUtils.fromTypeMirror(signature2); - - if (ElementUtils.getDirectSuperTypes(element1).contains(element2)) { - return -1; - } else if (ElementUtils.getDirectSuperTypes(element2).contains(element1)) { - return 1; - } - } - return ElementUtils.getSimpleName(signature1).compareTo(ElementUtils.getSimpleName(signature2)); - } - - public static List uniqueSortedTypes(Collection types, boolean reverse) { - if (types.isEmpty()) { - return new ArrayList<>(0); - } else if (types.size() <= 1) { - if (types instanceof List) { - return (List) types; - } else { - return new ArrayList<>(types); - } - } - Map sourceTypes = new HashMap<>(); - for (TypeMirror type : types) { - sourceTypes.put(ElementUtils.getTypeId(type), type); - } - return sortTypes(new ArrayList<>(sourceTypes.values()), reverse); - } - - public static int compareMethod(ExecutableElement method1, ExecutableElement method2) { - List parameters1 = method1.getParameters(); - List parameters2 = method2.getParameters(); - if (parameters1.size() != parameters2.size()) { - return Integer.compare(parameters1.size(), parameters2.size()); - } - - int result = 0; - for (int i = 0; i < parameters1.size(); i++) { - VariableElement var1 = parameters1.get(i); - VariableElement var2 = parameters2.get(i); - result = compareType(var1.asType(), var2.asType()); - if (result != 0) { - return result; - } - } - - result = method1.getSimpleName().toString().compareTo(method2.getSimpleName().toString()); - if (result == 0) { - // if still no difference sort by enclosing type name - TypeElement enclosingType1 = ElementUtils.findNearestEnclosingType(method1); - TypeElement enclosingType2 = ElementUtils.findNearestEnclosingType(method2); - result = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString()); - } - return result; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/AbstractCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/AbstractCompiler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +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.dsl.processor.java.compiler; - -import java.lang.reflect.*; - -public abstract class AbstractCompiler implements Compiler { - - protected static Object method(Object o, String methodName) throws Exception { - Method method = o.getClass().getMethod(methodName); - method.setAccessible(true); - return method.invoke(o); - } - - protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception { - Method method = o.getClass().getMethod(methodName, paramTypes); - method.setAccessible(true); - return method.invoke(o, values); - } - - protected static Object field(Object o, String fieldName) throws Exception { - if (o == null) { - return null; - } - Class clazz = o.getClass(); - Field field = null; - try { - field = clazz.getField(fieldName); - } catch (NoSuchFieldException e) { - while (clazz != null) { - try { - field = clazz.getDeclaredField(fieldName); - break; - } catch (NoSuchFieldException e1) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw e; - } - } - field.setAccessible(true); - return field.get(o); - } - - protected static String parseHeader(String content) { - int index = content.indexOf("/*"); - if (index == -1) { - return null; - } - if (!content.substring(0, index).trim().equals("")) { - // just whitespace before - return null; - } - - int endIndex = content.indexOf("*/", index); - if (endIndex == -1) { - return null; - } - return content.substring(index, endIndex + 2); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/Compiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/Compiler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +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.dsl.processor.java.compiler; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; - -public interface Compiler { - - String getMethodBody(ProcessingEnvironment env, ExecutableElement method); - - String getHeaderComment(ProcessingEnvironment env, Element type); - - List getEnclosedElementsInDeclarationOrder(TypeElement type); - - List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/CompilerFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/CompilerFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +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.dsl.processor.java.compiler; - -import javax.lang.model.element.*; - -public class CompilerFactory { - - private static Compiler javac; - private static Compiler jdt; - - public static Compiler getCompiler(Element currentElement) { - if (JavaCCompiler.isValidElement(currentElement)) { - if (javac == null) { - javac = new JavaCCompiler(); - } - return javac; - } else if (JDTCompiler.isValidElement(currentElement)) { - if (jdt == null) { - jdt = new JDTCompiler(); - } - return jdt; - } else { - throw new UnsupportedOperationException("Unsupported compiler for element " + currentElement.getClass().getName() + "."); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/JDTCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/JDTCompiler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2012, 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.dsl.processor.java.compiler; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class JDTCompiler extends AbstractCompiler { - - public static boolean isValidElement(Element currentElement) { - try { - Class elementClass = Class.forName("org.eclipse.jdt.internal.compiler.apt.model.ElementImpl"); - return elementClass.isAssignableFrom(currentElement.getClass()); - } catch (ClassNotFoundException e) { - return false; - } - } - - public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { - return sortBySourceOrder(new ArrayList<>(environment.getElementUtils().getAllMembers(type))); - - } - - public List getEnclosedElementsInDeclarationOrder(TypeElement type) { - return sortBySourceOrder(new ArrayList<>(type.getEnclosedElements())); - } - - private static List sortBySourceOrder(List elements) { - Map> groupedByEnclosing = new HashMap<>(); - for (Element element : elements) { - Element enclosing = element.getEnclosingElement(); - List grouped = groupedByEnclosing.get(enclosing); - if (grouped == null) { - grouped = new ArrayList<>(); - groupedByEnclosing.put((TypeElement) enclosing, grouped); - } - grouped.add(element); - } - - for (TypeElement enclosing : groupedByEnclosing.keySet()) { - Collections.sort(groupedByEnclosing.get(enclosing), createSourceOrderComparator(enclosing)); - } - - if (groupedByEnclosing.size() == 1) { - return groupedByEnclosing.get(groupedByEnclosing.keySet().iterator().next()); - } else { - List enclosingTypes = new ArrayList<>(groupedByEnclosing.keySet()); - - Collections.sort(enclosingTypes, new Comparator() { - public int compare(TypeElement o1, TypeElement o2) { - if (ElementUtils.isSubtype(o1.asType(), o2.asType())) { - return 1; - } else { - return -1; - } - } - }); - - List sourceOrderElements = new ArrayList<>(); - for (TypeElement typeElement : enclosingTypes) { - sourceOrderElements.addAll(groupedByEnclosing.get(typeElement)); - } - return sourceOrderElements; - } - - } - - private static Comparator createSourceOrderComparator(final TypeElement enclosing) { - - Comparator comparator = new Comparator() { - - final List declarationOrder = lookupDeclarationOrder(enclosing); - - public int compare(Element o1, Element o2) { - try { - Element enclosing1Element = o1.getEnclosingElement(); - Element enclosing2Element = o2.getEnclosingElement(); - - if (!ElementUtils.typeEquals(enclosing1Element.asType(), enclosing2Element.asType())) { - throw new AssertionError(); - } - - Object o1Binding = field(o1, "_binding"); - Object o2Binding = field(o2, "_binding"); - - int i1 = declarationOrder.indexOf(o1Binding); - int i2 = declarationOrder.indexOf(o2Binding); - - if (i1 == -1 || i2 == -1) { - return 0; - } - - return i1 - i2; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; - return comparator; - } - - private static List lookupDeclarationOrder(TypeElement type) { - - List declarationOrder; - try { - Object binding = field(type, "_binding"); - Class sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); - Class binaryTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding"); - - declarationOrder = null; - if (sourceTypeBinding.isAssignableFrom(binding.getClass())) { - declarationOrder = findSourceTypeOrder(binding); - } else if (binaryTypeBinding.isAssignableFrom(binding.getClass())) { - declarationOrder = findBinaryTypeOrder(binding); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - - return declarationOrder; - } - - private static List findBinaryTypeOrder(Object binding) throws Exception { - Object binaryType = lookupBinaryType(binding); - final Object[] sortedMethods = (Object[]) method(binaryType, "getMethods"); - - List sortedElements = new ArrayList<>(); - if (sortedMethods != null) { - sortedElements.addAll(Arrays.asList(sortedMethods)); - } - final Object[] sortedFields = (Object[]) method(binaryType, "getFields"); - if (sortedFields != null) { - sortedElements.addAll(Arrays.asList(sortedFields)); - } - final Object[] sortedTypes = (Object[]) method(binaryType, "getMemberTypes", new Class[0]); - if (sortedTypes != null) { - sortedElements.addAll(Arrays.asList(sortedTypes)); - } - - Collections.sort(sortedElements, new Comparator() { - public int compare(Object o1, Object o2) { - try { - int structOffset1 = (int) field(o1, "structOffset"); - int structOffset2 = (int) field(o2, "structOffset"); - return structOffset1 - structOffset2; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - - Class binaryMethod = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryMethod"); - Class binaryField = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryField"); - Class nestedType = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryNestedType"); - - List bindings = new ArrayList<>(); - for (Object sortedElement : sortedElements) { - Class elementClass = sortedElement.getClass(); - if (binaryMethod.isAssignableFrom(elementClass)) { - char[] selector = (char[]) method(sortedElement, "getSelector"); - Object[] foundBindings = (Object[]) method(binding, "getMethods", new Class[]{char[].class}, selector); - if (foundBindings == null || foundBindings.length == 0) { - continue; - } else if (foundBindings.length == 1) { - bindings.add(foundBindings[0]); - } else { - char[] idescriptor = (char[]) method(sortedElement, "getMethodDescriptor"); - for (Object foundBinding : foundBindings) { - char[] descriptor = (char[]) method(foundBinding, "signature"); - if (descriptor == null && idescriptor == null || Arrays.equals(descriptor, idescriptor)) { - bindings.add(foundBinding); - break; - } - } - } - } else if (binaryField.isAssignableFrom(elementClass)) { - char[] selector = (char[]) method(sortedElement, "getName"); - Object foundField = method(binding, "getField", new Class[]{char[].class, boolean.class}, selector, true); - if (foundField != null) { - bindings.add(foundField); - } - } else if (nestedType.isAssignableFrom(elementClass)) { - char[] selector = (char[]) method(sortedElement, "getSourceName"); - Object foundType = method(binding, "getMemberType", new Class[]{char[].class}, selector); - if (foundType != null) { - bindings.add(foundType); - } - } else { - throw new AssertionError("Unexpected encountered type " + elementClass); - } - } - - return bindings; - } - - private static Object lookupBinaryType(Object binding) throws Exception { - Object lookupEnvironment = field(binding, "environment"); - Object compoundClassName = field(binding, "compoundName"); - Object nameEnvironment = field(lookupEnvironment, "nameEnvironment"); - Object nameEnvironmentAnswer = method(nameEnvironment, "findType", new Class[]{char[][].class}, compoundClassName); - Object binaryType = method(nameEnvironmentAnswer, "getBinaryType", new Class[0]); - return binaryType; - } - - private static List findSourceTypeOrder(Object binding) throws Exception { - Object referenceContext = field(field(binding, "scope"), "referenceContext"); - - TreeMap orderedBindings = new TreeMap<>(); - - collectSourceOrder(orderedBindings, referenceContext, "methods"); - collectSourceOrder(orderedBindings, referenceContext, "fields"); - collectSourceOrder(orderedBindings, referenceContext, "memberTypes"); - - return new ArrayList<>(orderedBindings.values()); - } - - private static void collectSourceOrder(TreeMap orderedBindings, Object referenceContext, String fieldName) throws Exception { - Object[] declarations = (Object[]) field(referenceContext, fieldName); - if (declarations != null) { - for (int i = 0; i < declarations.length; i++) { - Integer declarationSourceStart = (Integer) field(declarations[i], "declarationSourceStart"); - orderedBindings.put(declarationSourceStart, field(declarations[i], "binding")); - } - } - } - - @Override - public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { - try { - - char[] source = getSource(method); - if (source == null) { - return null; - } - - /* - * AbstractMethodDeclaration decl = - * ((MethodBinding)(((ElementImpl)method)._binding)).sourceMethod(); int bodyStart = - * decl.bodyStart; int bodyEnd = decl.bodyEnd; - */ - Object decl = method(field(method, "_binding"), "sourceMethod"); - int bodyStart = (int) field(decl, "bodyStart"); - int bodyEnd = (int) field(decl, "bodyEnd"); - - int length = bodyEnd - bodyStart; - char[] target = new char[length]; - System.arraycopy(source, bodyStart, target, 0, length); - - return new String(target); - } catch (Exception e) { - return ElementUtils.printException(e); - } - } - - private static char[] getSource(Element element) throws Exception { - /* - * Binding binding = ((ElementImpl)element)._binding; char[] source = null; if (binding - * instanceof MethodBinding) { source = ((MethodBinding) - * binding).sourceMethod().compilationResult.getCompilationUnit().getContents(); } else if - * (binding instanceof SourceTypeBinding) { source = - * ((SourceTypeBinding)binding).scope.referenceContext - * .compilationResult.compilationUnit.getContents(); } return source; - */ - - Object binding = field(element, "_binding"); - Class methodBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.MethodBinding"); - Class referenceBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); - - char[] source = null; - if (methodBindingClass.isAssignableFrom(binding.getClass())) { - Object sourceMethod = method(binding, "sourceMethod"); - if (sourceMethod == null) { - return null; - } - source = (char[]) method(method(field(sourceMethod, "compilationResult"), "getCompilationUnit"), "getContents"); - } else if (referenceBindingClass.isAssignableFrom(binding.getClass())) { - source = (char[]) method(field(field(field(field(binding, "scope"), "referenceContext"), "compilationResult"), "compilationUnit"), "getContents"); - } - return source; - } - - @Override - public String getHeaderComment(ProcessingEnvironment env, Element type) { - try { - char[] source = getSource(type); - if (source == null) { - return null; - } - return parseHeader(new String(source)); - } catch (Exception e) { - return ElementUtils.printException(e); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/JavaCCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/compiler/JavaCCompiler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +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.dsl.processor.java.compiler; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class JavaCCompiler extends AbstractCompiler { - - public static boolean isValidElement(Element currentElement) { - try { - Class elementClass = Class.forName("com.sun.tools.javac.code.Symbol"); - return elementClass.isAssignableFrom(currentElement.getClass()); - } catch (ClassNotFoundException e) { - return false; - } - } - - public List getEnclosedElementsInDeclarationOrder(TypeElement type) { - return type.getEnclosedElements(); - } - - public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { - return environment.getElementUtils().getAllMembers(type); - } - - private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class}; - private static final Class[] getCharContentSignature = new Class[]{boolean.class}; - - @Override - public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { - try { - /* - * if (false) { Pair treeAndTopLevel = ((JavacElements) - * env.getElementUtils()).getTreeAndTopLevel(method, null, null); JCBlock block = - * ((JCMethodDecl) treeAndTopLevel.fst).getBody(); int startPos = block.pos; int endPos - * = block.endpos; String methodBody = - * treeAndTopLevel.snd.getSourceFile().getCharContent(true).subSequence(startPos + 1, - * endPos).toString(); return methodBody; } - */ - - Object treeAndTopLevel = getTreeAndTopLevel(env, method); - Object block = method(field(treeAndTopLevel, "fst"), "getBody"); - int startPos = (int) field(block, "pos"); - int endPos = (int) field(block, "endpos"); - return getContent(treeAndTopLevel).subSequence(startPos + 1, endPos).toString(); - } catch (Exception e) { - return ElementUtils.printException(e); - } - } - - private static CharSequence getContent(Object treeAndTopLevel) throws Exception { - /* - * CharSequence content = treeAndTopLevel.snd.getSourceFile().getCharContent(true); - */ - return (CharSequence) method(method(field(treeAndTopLevel, "snd"), "getSourceFile"), "getCharContent", getCharContentSignature, true); - } - - private static Object getTreeAndTopLevel(ProcessingEnvironment env, Element element) throws Exception { - /* - * Pair treeAndTopLevel = ((JavacElements) - * env.getElementUtils()).getTreeAndTopLevel(method, null, null); - */ - return method(method(env, "getElementUtils"), "getTreeAndTopLevel", getTreeAndTopLevelSignature, element, null, null); - } - - @Override - public String getHeaderComment(ProcessingEnvironment env, Element type) { - try { - String content = getContent(getTreeAndTopLevel(env, type)).toString(); - return parseHeader(content); - } catch (Exception e) { - return ElementUtils.printException(e); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationMirror.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationMirror.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class CodeAnnotationMirror implements AnnotationMirror { - - private final DeclaredType annotationType; - private final Map values = new LinkedHashMap<>(); - - public CodeAnnotationMirror(DeclaredType annotationType) { - this.annotationType = annotationType; - } - - @Override - public DeclaredType getAnnotationType() { - return annotationType; - } - - @Override - public Map getElementValues() { - return values; - } - - public void setElementValue(ExecutableElement method, AnnotationValue value) { - values.put(method, value); - } - - public ExecutableElement findExecutableElement(String name) { - return ElementUtils.findExecutableElement(annotationType, name); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationValue.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationValue.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public class CodeAnnotationValue implements AnnotationValue { - - private final Object value; - - public CodeAnnotationValue(Object value) { - Objects.requireNonNull(value); - if ((value instanceof AnnotationMirror) || (value instanceof List) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) || - (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) || - (value instanceof String) || (value instanceof TypeMirror)) { - this.value = value; - } else { - throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName()); - } - } - - @Override - public Object getValue() { - return value; - } - - @SuppressWarnings("unchecked") - @Override - public R accept(AnnotationValueVisitor v, P p) { - if (value instanceof AnnotationMirror) { - return v.visitAnnotation((AnnotationMirror) value, p); - } else if (value instanceof List) { - return v.visitArray((List) value, p); - } else if (value instanceof Boolean) { - return v.visitBoolean((boolean) value, p); - } else if (value instanceof Byte) { - return v.visitByte((byte) value, p); - } else if (value instanceof Character) { - return v.visitChar((char) value, p); - } else if (value instanceof Double) { - return v.visitDouble((double) value, p); - } else if (value instanceof VariableElement) { - return v.visitEnumConstant((VariableElement) value, p); - } else if (value instanceof Float) { - return v.visitFloat((float) value, p); - } else if (value instanceof Integer) { - return v.visitInt((int) value, p); - } else if (value instanceof Long) { - return v.visitLong((long) value, p); - } else if (value instanceof Short) { - return v.visitShort((short) value, p); - } else if (value instanceof String) { - return v.visitString((String) value, p); - } else if (value instanceof TypeMirror) { - return v.visitType((TypeMirror) value, p); - } else { - return v.visitUnknown(this, p); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeCompilationUnit.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeCompilationUnit.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public class CodeCompilationUnit extends CodeElement { - - public CodeCompilationUnit() { - super(Collections. emptySet()); - } - - @Override - public TypeMirror asType() { - throw new UnsupportedOperationException(); - } - - @Override - public ElementKind getKind() { - return ElementKind.OTHER; - } - - @Override - public Name getSimpleName() { - throw new UnsupportedOperationException(); - } - - @Override - public R accept(ElementVisitor v, P p) { - for (Element type : getEnclosedElements()) { - if (type.getKind().isClass()) { - type.accept(v, p); - } else { - throw new ClassCastException(type.getClass().getName()); - } - } - return null; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +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.dsl.processor.java.model; - -import java.io.*; -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.java.transform.*; - -public abstract class CodeElement implements Element, GeneratedElement { - - private final Set modifiers; - private List annotations; - private List enclosedElements; - - private Element enclosingElement; - - private Element generatorElement; - private AnnotationMirror generatorAnnotationMirror; - - public CodeElement(Set modifiers) { - this.modifiers = new LinkedHashSet<>(modifiers); - } - - @Override - public void setGeneratorAnnotationMirror(AnnotationMirror mirror) { - this.generatorAnnotationMirror = mirror; - } - - @Override - public void setGeneratorElement(Element element) { - this.generatorElement = element; - } - - @Override - public AnnotationMirror getGeneratorAnnotationMirror() { - return generatorAnnotationMirror; - } - - @Override - public Element getGeneratorElement() { - return generatorElement; - } - - public T add(T element) { - if (element == null) { - throw new NullPointerException(); - } - getEnclosedElements().add(element); - return element; - } - - public T addOptional(T element) { - if (element != null) { - add(element); - } - return element; - } - - public void remove(E element) { - getEnclosedElements().remove(element); - } - - @Override - public Set getModifiers() { - return modifiers; - } - - @Override - public List getEnclosedElements() { - if (enclosedElements == null) { - enclosedElements = parentableList(this, new ArrayList()); - } - return enclosedElements; - } - - @Override - public List getAnnotationMirrors() { - if (annotations == null) { - annotations = parentableList(this, new ArrayList()); - } - return annotations; - } - - /** - * Support JDK8 langtools. - * - * @param annotationType - */ - public A[] getAnnotationsByType(Class annotationType) { - throw new UnsupportedOperationException(); - } - - /** - * Support for some JDK8 builds. (remove after jdk8 is released) - * - * @param annotationType - */ - public A[] getAnnotations(Class annotationType) { - throw new UnsupportedOperationException(); - } - - /** - * Support for some JDK8 builds. (remove after jdk8 is released) - * - * @param annotationType - */ - public A getAnnotation(Class annotationType) { - throw new UnsupportedOperationException(); - } - - public void addAnnotationMirror(AnnotationMirror annotationMirror) { - getAnnotationMirrors().add(annotationMirror); - } - - public void setEnclosingElement(Element parent) { - this.enclosingElement = parent; - } - - public Element getEnclosingElement() { - return enclosingElement; - } - - public CodeTypeElement getEnclosingClass() { - Element p = enclosingElement; - while (p != null && p.getKind() != ElementKind.CLASS && p.getKind() != ElementKind.ENUM) { - p = p.getEnclosingElement(); - } - return (CodeTypeElement) p; - } - - List parentableList(Element parent, List list) { - return new ParentableList<>(parent, list); - } - - @Override - public String toString() { - StringBuilderCodeWriter codeWriter = new StringBuilderCodeWriter(); - accept(codeWriter, null); - return codeWriter.getString(); - } - - private static class StringBuilderCodeWriter extends AbstractCodeWriter { - - public StringBuilderCodeWriter() { - this.writer = new CharArrayWriter(); - } - - @Override - protected Writer createWriter(CodeTypeElement clazz) throws IOException { - return writer; - } - - public String getString() { - return new String(((CharArrayWriter) writer).toCharArray()).trim(); - } - - } - - private static class ParentableList implements List { - - private final Element parent; - private final List delegate; - - public ParentableList(Element parent, List delegate) { - this.parent = parent; - this.delegate = delegate; - } - - private void addImpl(T element) { - if (element != null) { - if (element instanceof CodeElement) { - ((CodeElement) element).setEnclosingElement(parent); - } - } - } - - private static void removeImpl(Object element) { - if (element instanceof CodeElement) { - ((CodeElement) element).setEnclosingElement(null); - } - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.contains(o); - } - - @Override - public Iterator iterator() { - return delegate.iterator(); - } - - @Override - public Object[] toArray() { - return delegate.toArray(); - } - - @Override - public E[] toArray(E[] a) { - return delegate.toArray(a); - } - - @Override - public boolean add(T e) { - addImpl(e); - return delegate.add(e); - } - - @Override - public boolean remove(Object o) { - boolean removed = delegate.remove(o); - if (removed) { - removeImpl(o); - } - return removed; - } - - @Override - public boolean containsAll(Collection c) { - return delegate.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - if (c != null) { - for (T t : c) { - addImpl(t); - } - } - return delegate.addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - if (c != null) { - for (T t : c) { - addImpl(t); - } - } - return delegate.addAll(index, c); - } - - @Override - public boolean removeAll(Collection c) { - if (c != null) { - for (Object t : c) { - removeImpl(t); - } - } - return delegate.removeAll(c); - } - - @Override - public String toString() { - return delegate.toString(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException("Not supported by parentable list"); - } - - @Override - public void clear() { - for (Object e : this) { - removeImpl(e); - } - delegate.clear(); - } - - @Override - public T get(int index) { - return delegate.get(index); - } - - @Override - public T set(int index, T element) { - removeImpl(delegate.get(index)); - addImpl(element); - return delegate.set(index, element); - } - - @Override - public void add(int index, T element) { - addImpl(element); - delegate.add(index, element); - } - - @Override - public T remove(int index) { - T element = delegate.remove(index); - removeImpl(element); - return element; - } - - @Override - public int indexOf(Object o) { - return delegate.indexOf(o); - } - - @Override - public int lastIndexOf(Object o) { - return delegate.lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - return delegate.listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return delegate.listIterator(index); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return new ParentableList<>(parent, delegate.subList(fromIndex, toIndex)); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.util.*; - -public abstract class CodeElementScanner extends ElementScanner7 { - - @Override - public final R visitExecutable(ExecutableElement e, P p) { - if (!(e instanceof CodeExecutableElement)) { - throw new ClassCastException(e.toString()); - } - return visitExecutable(cast(e, CodeExecutableElement.class), p); - } - - public R visitExecutable(CodeExecutableElement e, P p) { - R ret = super.visitExecutable(e, p); - if (e.getBodyTree() != null) { - visitTree(e.getBodyTree(), p, e); - } - return ret; - } - - @Override - public R visitVariable(VariableElement e, P p) { - if (e instanceof CodeVariableElement) { - CodeTree init = ((CodeVariableElement) e).getInit(); - if (init != null) { - visitTree(init, p, e); - } - } - return super.visitVariable(e, p); - } - - @Override - public R visitPackage(PackageElement e, P p) { - return super.visitPackage(e, p); - } - - @Override - public final R visitType(TypeElement e, P p) { - return visitType(cast(e, CodeTypeElement.class), p); - } - - public R visitType(CodeTypeElement e, P p) { - return super.visitType(e, p); - } - - @Override - public R visitTypeParameter(TypeParameterElement e, P p) { - return super.visitTypeParameter(e, p); - } - - private static E cast(Element element, Class clazz) { - return clazz.cast(element); - } - - public void visitTree(CodeTree e, P p, Element parent) { - List elements = e.getEnclosedElements(); - if (elements != null) { - for (CodeTree tree : e.getEnclosedElements()) { - visitTree(tree, p, parent); - } - } - } - - @SuppressWarnings("unused") - public void visitImport(CodeImport e, P p) { - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class CodeExecutableElement extends CodeElement implements ExecutableElement { - - private final List throwables = new ArrayList<>(); - private final List parameters = parentableList(this, new ArrayList()); - - private TypeMirror returnType; - private Name name; - - private CodeTree bodyTree; - private String body; - private AnnotationValue defaultValue; - private boolean varArgs; - - public CodeExecutableElement(TypeMirror returnType, String name) { - super(ElementUtils.modifiers()); - this.returnType = returnType; - this.name = CodeNames.of(name); - } - - public CodeExecutableElement(Set modifiers, TypeMirror returnType, String name, CodeVariableElement... parameters) { - super(modifiers); - this.returnType = returnType; - this.name = CodeNames.of(name); - for (CodeVariableElement codeParameter : parameters) { - addParameter(codeParameter); - } - } - - public void setVisibility(Modifier visibility) { - ElementUtils.setVisibility(getModifiers(), visibility); - } - - public Modifier getVisibility() { - return ElementUtils.getVisibility(getModifiers()); - } - - /* Support JDK8 langtools. */ - public boolean isDefault() { - return false; - } - - @Override - public List getThrownTypes() { - return throwables; - } - - @Override - public TypeMirror asType() { - return returnType; - } - - @Override - public ElementKind getKind() { - if (getReturnType() == null) { - return ElementKind.CONSTRUCTOR; - } else { - return ElementKind.METHOD; - } - } - - @Override - public List getTypeParameters() { - return Collections.emptyList(); - } - - public void setVarArgs(boolean varargs) { - this.varArgs = varargs; - } - - @Override - public boolean isVarArgs() { - return varArgs; - } - - public void setDefaultValue(AnnotationValue defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public AnnotationValue getDefaultValue() { - return defaultValue; - } - - @Override - public Name getSimpleName() { - return name; - } - - public CodeTreeBuilder getBuilder() { - CodeTree tree = this.bodyTree; - return createBuilder().tree(tree); - } - - public CodeTreeBuilder createBuilder() { - CodeTreeBuilder builder = new CodeTreeBuilder(null); - builder.setEnclosingElement(this); - this.bodyTree = builder.getTree(); - this.body = null; - return builder; - } - - public CodeTreeBuilder appendBuilder() { - CodeTreeBuilder builder = new CodeTreeBuilder(null); - builder.setEnclosingElement(this); - if (bodyTree != null) { - builder.tree(bodyTree); - } - this.bodyTree = builder.getTree(); - this.body = null; - return builder; - } - - public void setBodyTree(CodeTree body) { - this.bodyTree = body; - } - - public CodeTree getBodyTree() { - return bodyTree; - } - - public TypeMirror getReturnType() { - return returnType; - } - - @Override - public List getParameters() { - return parameters; - } - - public TypeMirror[] getParameterTypes() { - TypeMirror[] types = new TypeMirror[getParameters().size()]; - for (int i = 0; i < types.length; i++) { - types[i] = parameters.get(i).asType(); - } - return types; - } - - public void setReturnType(TypeMirror type) { - returnType = type; - } - - public void addParameter(VariableElement parameter) { - parameters.add(parameter); - } - - public void addThrownType(TypeMirror thrownType) { - throwables.add(thrownType); - } - - public void setSimpleName(Name name) { - this.name = name; - } - - public void setBody(String body) { - this.body = body; - } - - public String getBody() { - return body; - } - - @Override - public R accept(ElementVisitor v, P p) { - return v.visitExecutable(this, p); - } - - public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) { - CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString()); - for (TypeMirror thrownType : method.getThrownTypes()) { - copy.addThrownType(thrownType); - } - copy.setDefaultValue(method.getDefaultValue()); - - for (AnnotationMirror mirror : method.getAnnotationMirrors()) { - copy.addAnnotationMirror(mirror); - } - for (VariableElement var : method.getParameters()) { - copy.addParameter(CodeVariableElement.clone(var)); - } - for (Element element : method.getEnclosedElements()) { - copy.add(element); - } - copy.getModifiers().addAll(method.getModifiers()); - copy.setVarArgs(method.isVarArgs()); - return copy; - } - - public TypeMirror getReceiverType() { - throw new UnsupportedOperationException(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeImport.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeImport.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +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.dsl.processor.java.model; - -import java.util.*; - -public class CodeImport implements Comparable { - - private final String packageName; - private final String symbolName; - private final boolean staticImport; - - public CodeImport(String packageName, String symbolName, boolean staticImport) { - this.packageName = packageName; - this.symbolName = symbolName; - this.staticImport = staticImport; - } - - public String getPackageName() { - return packageName; - } - - public String getSymbolName() { - return symbolName; - } - - public boolean isStaticImport() { - return staticImport; - } - - @Override - public int compareTo(CodeImport o) { - if (staticImport && !o.staticImport) { - return 1; - } else if (!staticImport && o.staticImport) { - return -1; - } else { - int result = getPackageName().compareTo(o.getPackageName()); - if (result == 0) { - return getSymbolName().compareTo(o.getSymbolName()); - } - return result; - } - } - - public

void accept(CodeElementScanner s, P p) { - s.visitImport(this, p); - } - - @Override - public int hashCode() { - return Objects.hash(packageName, symbolName, staticImport); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof CodeImport) { - CodeImport otherImport = (CodeImport) obj; - return getPackageName().equals(otherImport.getPackageName()) && getSymbolName().equals(otherImport.getSymbolName()) // - && staticImport == otherImport.staticImport; - } - return super.equals(obj); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeNames.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeNames.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; - -public abstract class CodeNames { - - private static Map names = new HashMap<>(); - - public static Name of(String value) { - Name name = names.get(value); - if (name == null) { - name = new NameImpl(value); - names.put(value, name); - } - return name; - } - - private static class NameImpl implements Name { - - private final String name; - - public NameImpl(String name) { - this.name = name; - } - - @Override - public int length() { - return name.length(); - } - - @Override - public char charAt(int index) { - return name.charAt(index); - } - - @Override - public CharSequence subSequence(int start, int end) { - return name.subSequence(start, end); - } - - @Override - public boolean contentEquals(CharSequence cs) { - return name.contentEquals(cs); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Name) { - return ((Name) obj).contentEquals(name); - } - return super.equals(obj); - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return name; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTree.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTree.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.type.*; - -public class CodeTree { - - private final CodeTreeKind kind; - - private CodeTree parent; - - private TypeMirror type; - private final String string; - - private List children; - - CodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) { - this.parent = parent; - this.kind = kind; - this.type = type; - this.string = string; - } - - public void setParent(CodeTree parent) { - this.parent = parent; - } - - public CodeTree getParent() { - return parent; - } - - public TypeMirror getType() { - return type; - } - - public void add(CodeTree element) { - if (children == null) { - children = new ArrayList<>(); - } - element.setParent(this); - children.add(element); - } - - public final List getEnclosedElements() { - return children; - } - - public final CodeTreeKind getCodeKind() { - return kind; - } - - public String getString() { - return string; - } - - public void setType(TypeMirror type) { - this.type = type; - } - - public boolean isEmpty() { - return children == null || children.isEmpty(); - } - - public boolean containsKind(CodeTreeKind k) { - if (this.kind == k) { - return true; - } - if (children != null) { - for (CodeTree child : children) { - if (child.containsKind(k)) { - return true; - } - } - } - return false; - } - - public boolean isSingleLine() { - return !containsKind(CodeTreeKind.NEW_LINE); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,882 +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.dsl.processor.java.model; - -import static com.oracle.truffle.dsl.processor.java.model.CodeTreeKind.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class CodeTreeBuilder { - - private BuilderCodeTree currentElement; - private final BuilderCodeTree root; - - private int treeCount; - private Element enclosingElement; - - public CodeTreeBuilder(CodeTreeBuilder parent) { - this.root = new BuilderCodeTree(null, GROUP, null, null); - this.currentElement = root; - if (parent != null) { - this.enclosingElement = parent.enclosingElement; - } - } - - public void setEnclosingElement(Element enclosingElement) { - this.enclosingElement = enclosingElement; - } - - @Override - public String toString() { - return root.toString(); - } - - public int getTreeCount() { - return treeCount; - } - - public boolean isEmpty() { - return treeCount == 0; - } - - public CodeTreeBuilder statement(String statement) { - return startStatement().string(statement).end(); - } - - public CodeTreeBuilder statement(CodeTree statement) { - return startStatement().tree(statement).end(); - } - - public static CodeTreeBuilder createBuilder() { - return new CodeTreeBuilder(null); - } - - public static CodeTree singleString(String s) { - return createBuilder().string(s).build(); - } - - public static CodeTree singleType(TypeMirror s) { - return createBuilder().type(s).build(); - } - - private CodeTreeBuilder push(CodeTreeKind kind) { - return push(new BuilderCodeTree(currentElement, kind, null, null), kind == NEW_LINE); - } - - private CodeTreeBuilder push(String string) { - return push(new BuilderCodeTree(currentElement, CodeTreeKind.STRING, null, string), false); - } - - private CodeTreeBuilder push(TypeMirror type) { - return push(new BuilderCodeTree(currentElement, CodeTreeKind.TYPE, type, null), false); - } - - private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) { - return push(new BuilderCodeTree(currentElement, kind, type, string), kind == NEW_LINE); - } - - private CodeTreeBuilder push(BuilderCodeTree tree, boolean removeLast) { - if (currentElement != null) { - if (removeLast && !removeLastIfEnqueued(tree)) { - return this; - } - currentElement.add(tree); - } - switch (tree.getCodeKind()) { - case COMMA_GROUP: - case GROUP: - case INDENT: - currentElement = tree; - break; - } - treeCount++; - return this; - } - - private boolean removeLastIfEnqueued(BuilderCodeTree tree) { - if (tree.getCodeKind() == REMOVE_LAST) { - return !clearLastRec(tree.removeLast, currentElement.getEnclosedElements()); - } - List childTree = tree.getEnclosedElements(); - if (childTree != null && !childTree.isEmpty()) { - CodeTree last = childTree.get(0); - if (last instanceof BuilderCodeTree) { - if (!removeLastIfEnqueued((BuilderCodeTree) last)) { - childTree.remove(0); - } - } - } - return true; - } - - private void clearLast(CodeTreeKind kind) { - if (clearLastRec(kind, currentElement.getEnclosedElements())) { - treeCount--; - } else { - // delay clearing the last - BuilderCodeTree tree = new BuilderCodeTree(currentElement, REMOVE_LAST, null, null); - tree.removeLast = kind; - push(tree, false); - } - } - - public CodeTreeBuilder startStatement() { - startGroup(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - string(";").newLine(); - } - - @Override - public void afterEnd() { - } - }); - return this; - } - - public CodeTreeBuilder startGroup() { - return push(CodeTreeKind.GROUP); - } - - public CodeTreeBuilder startCommaGroup() { - return push(CodeTreeKind.COMMA_GROUP); - } - - public CodeTreeBuilder startCall(String callSite) { - return startCall((CodeTree) null, callSite); - } - - public CodeTreeBuilder startCall(String receiver, String callSite) { - if (receiver != null) { - return startCall(singleString(receiver), callSite); - } else { - return startCall(callSite); - } - } - - public CodeTreeBuilder startCall(CodeTree receiver, String callSite) { - if (receiver == null) { - return startGroup().string(callSite).startParanthesesCommaGroup().endAfter(); - } else { - return startGroup().tree(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter(); - } - } - - public CodeTreeBuilder startStaticCall(TypeMirror type, String methodName) { - return startGroup().push(CodeTreeKind.STATIC_METHOD_REFERENCE, type, methodName).startParanthesesCommaGroup().endAfter(); - } - - public CodeTreeBuilder startStaticCall(ExecutableElement method) { - return startStaticCall(ElementUtils.findNearestEnclosingType(method).asType(), method.getSimpleName().toString()); - } - - public CodeTreeBuilder staticReference(TypeMirror type, String fieldName) { - return push(CodeTreeKind.STATIC_FIELD_REFERENCE, type, fieldName); - } - - private CodeTreeBuilder endAndWhitespaceAfter() { - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string(" "); - end(); - } - }); - return this; - } - - private CodeTreeBuilder endAfter() { - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - end(); - } - }); - return this; - } - - private CodeTreeBuilder startParanthesesCommaGroup() { - startGroup(); - string("(").startCommaGroup(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string(")"); - } - }); - endAfter(); - return this; - } - - private CodeTreeBuilder startCurlyBracesCommaGroup() { - startGroup(); - string("{").startCommaGroup(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string("}"); - } - }); - endAfter(); - return this; - } - - public CodeTreeBuilder startParantheses() { - startGroup(); - string("(").startGroup(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string(")"); - } - }); - endAfter(); - return this; - } - - public CodeTreeBuilder doubleQuote(String s) { - return startGroup().string("\"" + s + "\"").end(); - } - - public CodeTreeBuilder string(String chunk1) { - return push(chunk1); - } - - public CodeTreeBuilder string(String chunk1, String chunk2) { - return push(GROUP).string(chunk1).string(chunk2).end(); - } - - public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3) { - return push(GROUP).string(chunk1).string(chunk2).string(chunk3).end(); - } - - public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4) { - return push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4).end(); - } - - public CodeTreeBuilder tree(CodeTree treeToAdd) { - if (treeToAdd instanceof BuilderCodeTree) { - return push((BuilderCodeTree) treeToAdd, true).end(); - } else { - BuilderCodeTree tree = new BuilderCodeTree(currentElement, GROUP, null, null); - currentElement.add(treeToAdd); - return push(tree, true).end(); - } - } - - public CodeTreeBuilder trees(CodeTree... trees) { - for (CodeTree tree : trees) { - tree(tree); - } - return this; - } - - public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4, String... chunks) { - push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4); - for (int i = 0; i < chunks.length; i++) { - string(chunks[i]); - } - return end(); - } - - public CodeTreeBuilder newLine() { - return push(NEW_LINE); - } - - public CodeTreeBuilder startWhile() { - return startGroup().string("while ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); - } - - public CodeTreeBuilder startDoBlock() { - return startGroup().string("do ").startBlock(); - } - - public CodeTreeBuilder startDoWhile() { - clearLast(CodeTreeKind.NEW_LINE); - return startStatement().string(" while ").startParanthesesCommaGroup().endAfter().startGroup().endAfter(); - } - - public CodeTreeBuilder startIf() { - return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); - } - - public CodeTreeBuilder startFor() { - return startGroup().string("for ").startParantheses().endAndWhitespaceAfter().startGroup().endAfter(); - } - - public boolean startIf(boolean elseIf) { - if (elseIf) { - startElseIf(); - } else { - startIf(); - } - return true; - } - - public CodeTreeBuilder startElseIf() { - clearLast(CodeTreeKind.NEW_LINE); - return startGroup().string(" else if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); - } - - public CodeTreeBuilder startElseBlock() { - clearLast(CodeTreeKind.NEW_LINE); - return startGroup().string(" else ").startBlock().endAfter(); - } - - private boolean clearLastRec(CodeTreeKind kind, List children) { - if (children == null) { - return false; - } - for (int i = children.size() - 1; i >= 0; i--) { - CodeTree child = children.get(i); - if (child.getCodeKind() == kind) { - children.remove(children.get(i)); - return true; - } else { - if (clearLastRec(kind, child.getEnclosedElements())) { - return true; - } - } - } - return false; - } - - public CodeTreeBuilder startCase() { - startGroup().string("case "); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - string(" :").newLine(); - } - - @Override - public void afterEnd() { - } - }); - return this; - } - - public CodeTreeBuilder caseDefault() { - return startGroup().string("default :").newLine().end(); - } - - public CodeTreeBuilder startSwitch() { - return startGroup().string("switch ").startParanthesesCommaGroup().endAndWhitespaceAfter(); - } - - public CodeTreeBuilder startReturn() { - ExecutableElement method = findMethod(); - if (method != null && ElementUtils.isVoid(method.getReturnType())) { - startGroup(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - string(";").newLine(); // complete statement to execute - } - - @Override - public void afterEnd() { - string("return").string(";").newLine(); // emit a return; - } - }); - return this; - } else { - return startStatement().string("return "); - } - } - - public CodeTreeBuilder startAssert() { - return startStatement().string("assert "); - } - - public CodeTreeBuilder startNewArray(ArrayType arrayType, CodeTree size) { - startGroup().string("new ").type(arrayType.getComponentType()).string("["); - if (size != null) { - tree(size); - } - string("]"); - if (size == null) { - string(" "); - startCurlyBracesCommaGroup().endAfter(); - } - return this; - } - - public CodeTreeBuilder startNew(TypeMirror uninializedNodeClass) { - return startGroup().string("new ").type(uninializedNodeClass).startParanthesesCommaGroup().endAfter(); - } - - public CodeTreeBuilder startNew(String typeName) { - return startGroup().string("new ").string(typeName).startParanthesesCommaGroup().endAfter(); - } - - public CodeTreeBuilder startIndention() { - return push(CodeTreeKind.INDENT); - } - - public CodeTreeBuilder end(int times) { - for (int i = 0; i < times; i++) { - end(); - } - return this; - } - - public CodeTreeBuilder end() { - BuilderCodeTree tree = currentElement; - EndCallback callback = tree.getAtEndListener(); - if (callback != null) { - callback.beforeEnd(); - toParent(); - callback.afterEnd(); - } else { - toParent(); - } - return this; - } - - private void toParent() { - CodeTree parentElement = currentElement.getParent(); - if (currentElement != root) { - this.currentElement = (BuilderCodeTree) parentElement; - } else { - this.currentElement = root; - } - } - - public CodeTreeBuilder startBlock() { - startGroup(); - string("{").newLine().startIndention(); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string("}").newLine(); - } - }); - endAfter(); - return this; - } - - private void registerCallBack(EndCallback callback) { - currentElement.registerAtEnd(callback); - } - - public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) { - if (!ElementUtils.isVoid(type)) { - startStatement(); - type(type); - string(" "); - string(name); - string(" = "); - defaultValue(type); - end(); // statement - } - return this; - } - - public CodeTreeBuilder declaration(TypeMirror type, String name, String init) { - return declaration(type, name, singleString(init)); - } - - public CodeTreeBuilder declaration(String type, String name, CodeTree init) { - startStatement(); - string(type); - string(" "); - string(name); - if (init != null) { - string(" = "); - tree(init); - } - end(); // statement - return this; - } - - public CodeTreeBuilder declaration(String type, String name, String init) { - return declaration(type, name, singleString(init)); - } - - public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) { - if (ElementUtils.isVoid(type)) { - startStatement(); - tree(init); - end(); - } else { - startStatement(); - type(type); - string(" "); - string(name); - if (init != null) { - string(" = "); - tree(init); - } - end(); // statement - } - return this; - } - - public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTreeBuilder init) { - if (init == this) { - throw new IllegalArgumentException("Recursive builder usage."); - } - return declaration(type, name, init.getTree()); - } - - public CodeTreeBuilder create() { - return new CodeTreeBuilder(this); - } - - public CodeTreeBuilder type(TypeMirror type) { - return push(type); - } - - public CodeTreeBuilder typeLiteral(TypeMirror type) { - return startGroup().type(ElementUtils.eraseGenericTypes(type)).string(".class").end(); - } - - private void assertRoot() { - if (currentElement != root) { - throw new IllegalStateException("CodeTreeBuilder was not ended properly."); - } - } - - public CodeTreeBuilder startCaseBlock() { - return startIndention(); - } - - public CodeTreeBuilder startThrow() { - return startStatement().string("throw "); - } - - public CodeTree getTree() { - assertRoot(); - return root; - } - - public CodeTree build() { - return root; - } - - public CodeTreeBuilder cast(TypeMirror type) { - string("(").type(type).string(") "); - return this; - } - - public CodeTreeBuilder cast(TypeMirror type, CodeTree content) { - if (ElementUtils.isVoid(type)) { - tree(content); - return this; - } else if (type.getKind() == TypeKind.DECLARED && ElementUtils.getQualifiedName(type).equals("java.lang.Object")) { - tree(content); - return this; - } else { - return startGroup().string("(").type(type).string(")").string(" ").tree(content).end(); - } - } - - public CodeTreeBuilder startSuperCall() { - return string("super").startParanthesesCommaGroup(); - } - - public CodeTreeBuilder returnFalse() { - return startReturn().string("false").end(); - } - - public CodeTreeBuilder returnStatement() { - return statement("return"); - } - - public ExecutableElement findMethod() { - if (enclosingElement != null && (enclosingElement.getKind() == ElementKind.METHOD || enclosingElement.getKind() == ElementKind.CONSTRUCTOR)) { - return (ExecutableElement) enclosingElement; - } - return null; - } - - public CodeTreeBuilder returnNull() { - return startReturn().string("null").end(); - } - - public CodeTreeBuilder returnTrue() { - return startReturn().string("true").end(); - } - - public CodeTreeBuilder instanceOf(CodeTree var, TypeMirror type) { - return tree(var).string(" instanceof ").type(type); - } - - public CodeTreeBuilder defaultValue(TypeMirror mirror) { - switch (mirror.getKind()) { - case VOID: - return string(""); - case ARRAY: - case DECLARED: - case PACKAGE: - case NULL: - return string("null"); - case BOOLEAN: - return string("false"); - case BYTE: - return string("(byte) 0"); - case CHAR: - return string("(char) 0"); - case DOUBLE: - return string("0.0D"); - case LONG: - return string("0L"); - case INT: - return string("0"); - case FLOAT: - return string("0.0F"); - case SHORT: - return string("(short) 0"); - default: - throw new AssertionError(); - } - } - - public CodeTreeBuilder startTryBlock() { - return string("try ").startBlock(); - } - - public CodeTreeBuilder startCatchBlock(TypeMirror exceptionType, String localVarName) { - clearLast(CodeTreeKind.NEW_LINE); - string(" catch (").type(exceptionType).string(" ").string(localVarName).string(") "); - return startBlock(); - } - - public CodeTreeBuilder startCatchBlock(TypeMirror[] exceptionTypes, String localVarName) { - clearLast(CodeTreeKind.NEW_LINE); - string(" catch ("); - - for (int i = 0; i < exceptionTypes.length; i++) { - if (i != 0) { - string(" | "); - } - type(exceptionTypes[i]); - } - - string(" ").string(localVarName).string(") "); - return startBlock(); - } - - public CodeTreeBuilder startFinallyBlock() { - clearLast(CodeTreeKind.NEW_LINE); - string(" finally "); - return startBlock(); - } - - public CodeTreeBuilder nullLiteral() { - return string("null"); - } - - private static class BuilderCodeTree extends CodeTree { - - private EndCallback atEndListener; - private CodeTreeKind removeLast; - - public BuilderCodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) { - super(parent, kind, type, string); - } - - public void registerAtEnd(EndCallback atEnd) { - if (this.atEndListener != null) { - this.atEndListener = new CompoundCallback(this.atEndListener, atEnd); - } else { - this.atEndListener = atEnd; - } - } - - public EndCallback getAtEndListener() { - return atEndListener; - } - - @Override - public String toString() { - final StringBuilder b = new StringBuilder(); - new Printer(b).visitTree(this, null, null); - return b.toString(); - } - - private static class CompoundCallback implements EndCallback { - - private final EndCallback callback1; - private final EndCallback callback2; - - public CompoundCallback(EndCallback callback1, EndCallback callback2) { - this.callback1 = callback1; - this.callback2 = callback2; - } - - @Override - public void afterEnd() { - callback1.afterEnd(); - callback2.afterEnd(); - } - - @Override - public void beforeEnd() { - callback1.beforeEnd(); - callback1.beforeEnd(); - } - } - - } - - private interface EndCallback { - - void beforeEnd(); - - void afterEnd(); - } - - private static class Printer extends CodeElementScanner { - - private int indent; - private boolean newLine; - private final String ln = "\n"; - - private final StringBuilder b; - - Printer(StringBuilder b) { - this.b = b; - } - - @Override - public void visitTree(CodeTree e, Void p, Element enclosingElement) { - switch (e.getCodeKind()) { - case COMMA_GROUP: - List children = e.getEnclosedElements(); - if (children != null) { - for (int i = 0; i < children.size(); i++) { - visitTree(children.get(i), p, enclosingElement); - if (i < e.getEnclosedElements().size() - 1) { - b.append(", "); - } - } - } - break; - case GROUP: - super.visitTree(e, p, enclosingElement); - break; - case INDENT: - indent(); - super.visitTree(e, p, enclosingElement); - dedent(); - break; - case NEW_LINE: - writeLn(); - break; - case STRING: - if (e.getString() != null) { - write(e.getString()); - } else { - write("null"); - } - break; - case TYPE: - write(ElementUtils.getSimpleName(e.getType())); - break; - default: - assert false; - return; - } - } - - private void indent() { - indent++; - } - - private void dedent() { - indent--; - } - - private void writeLn() { - write(ln); - newLine = true; - } - - private void write(String m) { - if (newLine && m != ln) { - writeIndent(); - newLine = false; - } - b.append(m); - } - - private void writeIndent() { - for (int i = 0; i < indent; i++) { - b.append(" "); - } - } - } - - public CodeTreeBuilder returnDefault() { - ExecutableElement method = findMethod(); - if (ElementUtils.isVoid(method.getReturnType())) { - returnStatement(); - } else { - startReturn().defaultValue(method.getReturnType()).end(); - } - return this; - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeKind.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeKind.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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.dsl.processor.java.model; - -public enum CodeTreeKind { - STATIC_FIELD_REFERENCE, - STATIC_METHOD_REFERENCE, - GROUP, - COMMA_GROUP, - REMOVE_LAST, - INDENT, - STRING, - NEW_LINE, - TYPE; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; - -public class CodeTypeElement extends CodeElement implements TypeElement { - - private final List imports = parentableList(this, new ArrayList()); - - private final PackageElement packageElement; - - private final Name simpleName; - private final Name packageName; - private Name qualifiedName; - - private final List implementsInterfaces = new ArrayList<>(); - private final ElementKind kind; - private TypeMirror superClass; - - private final DeclaredCodeTypeMirror mirror = new DeclaredCodeTypeMirror(this); - - public CodeTypeElement(Set modifiers, ElementKind kind, PackageElement packageElement, String simpleName) { - super(modifiers); - this.kind = kind; - this.packageElement = packageElement; - this.simpleName = CodeNames.of(simpleName); - if (this.packageElement != null) { - this.packageName = packageElement.getQualifiedName(); - } else { - this.packageName = CodeNames.of("default"); - } - this.qualifiedName = createQualifiedName(); - } - - @Override - public TypeMirror asType() { - return mirror; - } - - @Override - public ElementKind getKind() { - return kind; - } - - public boolean containsField(String name) { - for (VariableElement field : getFields()) { - if (field.getSimpleName().toString().equals(name)) { - return true; - } - } - return false; - } - - @Override - public NestingKind getNestingKind() { - return isTopLevelClass() ? NestingKind.TOP_LEVEL : NestingKind.LOCAL; - } - - @Override - public Element getEnclosingElement() { - if (isTopLevelClass()) { - return packageElement; - } else { - return super.getEnclosingElement(); - } - } - - @Override - public TypeMirror getSuperclass() { - return superClass; - } - - @Override - public List getInterfaces() { - return implementsInterfaces; - } - - @Override - public List getTypeParameters() { - return Collections.emptyList(); - } - - public boolean isTopLevelClass() { - return super.getEnclosingElement() instanceof CodeCompilationUnit || super.getEnclosingElement() == null; - } - - private Name createQualifiedName() { - TypeElement enclosingType = getEnclosingClass(); - if (enclosingType == null) { - return CodeNames.of(packageName + "." + simpleName); - } else { - return CodeNames.of(enclosingType.getQualifiedName() + "." + simpleName); - } - } - - @Override - public void setEnclosingElement(Element element) { - super.setEnclosingElement(element); - - // update qualified name on container change - this.qualifiedName = createQualifiedName(); - } - - public Name getPackageName() { - return packageName; - } - - @Override - public Name getQualifiedName() { - return qualifiedName; - } - - @Override - public Name getSimpleName() { - return simpleName; - } - - public void setSuperClass(TypeMirror superType) { - this.superClass = superType; - } - - public List getImports() { - return imports; - } - - public List getImplements() { - return implementsInterfaces; - } - - @Override - public int hashCode() { - return getQualifiedName().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } else if (obj instanceof TypeElement) { - return getQualifiedName().equals(((TypeElement) obj).getQualifiedName()); - } - return false; - } - - public List getFields() { - return ElementFilter.fieldsIn(getEnclosedElements()); - } - - public List getMethods() { - return ElementFilter.methodsIn(getEnclosedElements()); - } - - public List getInnerClasses() { - return ElementFilter.typesIn(getEnclosedElements()); - } - - @Override - public String toString() { - return getQualifiedName().toString(); - } - - @Override - public R accept(ElementVisitor v, P p) { - return v.visitType(this, p); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeMirror.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeMirror.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +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.dsl.processor.java.model; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public class CodeTypeMirror implements TypeMirror { - - private final TypeKind kind; - - public CodeTypeMirror(TypeKind kind) { - this.kind = kind; - } - - @Override - public TypeKind getKind() { - return kind; - } - - @Override - public R accept(TypeVisitor v, P p) { - throw new UnsupportedOperationException(); - } - - public static class WildcardTypeMirror extends CodeTypeMirror implements WildcardType { - - private final TypeMirror extendsBounds; - private final TypeMirror superBounds; - - public WildcardTypeMirror(TypeMirror extendsBounds, TypeMirror superBounds) { - super(TypeKind.WILDCARD); - this.extendsBounds = extendsBounds; - this.superBounds = superBounds; - } - - public TypeMirror getExtendsBound() { - return extendsBounds; - } - - public TypeMirror getSuperBound() { - return superBounds; - } - - } - - public static class ArrayCodeTypeMirror extends CodeTypeMirror implements ArrayType { - - private final TypeMirror component; - - public ArrayCodeTypeMirror(TypeMirror component) { - super(TypeKind.ARRAY); - this.component = component; - } - - @Override - public TypeMirror getComponentType() { - return component; - } - - } - - public static class DeclaredCodeTypeMirror extends CodeTypeMirror implements DeclaredType { - - private final TypeElement clazz; - private final List typeArguments; - - public DeclaredCodeTypeMirror(TypeElement clazz) { - this(clazz, Collections. emptyList()); - } - - public DeclaredCodeTypeMirror(TypeElement clazz, List typeArguments) { - super(TypeKind.DECLARED); - this.clazz = clazz; - this.typeArguments = typeArguments; - } - - @Override - public Element asElement() { - return clazz; - } - - @Override - public TypeMirror getEnclosingType() { - return clazz.getEnclosingElement().asType(); - } - - @Override - public List getTypeArguments() { - return typeArguments; - } - - @Override - public String toString() { - return clazz.getQualifiedName().toString(); - } - - } - - public List getAnnotationMirrors() { - throw new UnsupportedOperationException(); - } - - /** - * @param annotationType - */ - public A getAnnotation(Class annotationType) { - throw new UnsupportedOperationException(); - } - - /** - * @param annotationType - */ - public A[] getAnnotationsByType(Class annotationType) { - throw new UnsupportedOperationException(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public final class CodeVariableElement extends CodeElement implements VariableElement { - - private Name name; - private TypeMirror type; - private Object constantValue; - - private CodeTree init; - - public CodeVariableElement(TypeMirror type, String name) { - super(ElementUtils.modifiers()); - this.type = type; - this.name = CodeNames.of(name); - } - - public CodeVariableElement(Set modifiers, TypeMirror type, String name) { - super(modifiers); - this.type = type; - this.name = CodeNames.of(name); - } - - public CodeVariableElement(Set modifiers, TypeMirror type, String name, String init) { - this(modifiers, type, name); - if (init != null) { - this.init = new CodeTree(null, CodeTreeKind.STRING, null, init); - } - } - - public CodeTreeBuilder createInitBuilder() { - CodeTreeBuilder builder = new CodeTreeBuilder(null); - builder.setEnclosingElement(this); - init = builder.getTree(); - return builder; - } - - public void setInit(CodeTree init) { - this.init = init; - } - - public CodeTree getInit() { - return init; - } - - public Name getSimpleName() { - return name; - } - - public TypeMirror getType() { - return type; - } - - @Override - public TypeMirror asType() { - return type; - } - - @Override - public String toString() { - return super.toString() + "/* " + ElementUtils.getSimpleName(type) + "*/"; - } - - @Override - public ElementKind getKind() { - if (getEnclosingElement() instanceof ExecutableElement) { - return ElementKind.PARAMETER; - } else if (getEnclosingElement() instanceof TypeElement) { - return ElementKind.FIELD; - } else { - return ElementKind.PARAMETER; - } - } - - public void setConstantValue(Object constantValue) { - this.constantValue = constantValue; - } - - @Override - public Object getConstantValue() { - return constantValue; - } - - public String getName() { - return getSimpleName().toString(); - } - - public void setSimpleName(Name name) { - this.name = name; - } - - public void setName(String name) { - this.name = CodeNames.of(name); - } - - public void setType(TypeMirror type) { - this.type = type; - } - - @Override - public R accept(ElementVisitor v, P p) { - return v.visitVariable(this, p); - } - - public static CodeVariableElement clone(VariableElement var) { - CodeVariableElement copy = new CodeVariableElement(var.getModifiers(), var.asType(), var.getSimpleName().toString()); - copy.setConstantValue(var.getConstantValue()); - for (AnnotationMirror mirror : var.getAnnotationMirrors()) { - copy.addAnnotationMirror(mirror); - } - for (Element element : var.getEnclosedElements()) { - copy.add(element); - } - return copy; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +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.dsl.processor.java.model; - -import javax.lang.model.element.*; - -public interface GeneratedElement { - - AnnotationMirror getGeneratorAnnotationMirror(); - - void setGeneratorAnnotationMirror(AnnotationMirror mirror); - - Element getGeneratorElement(); - - void setGeneratorElement(Element element); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public final class GeneratedPackageElement extends CodeElement implements PackageElement { - - private final Name qualifiedName; - private final Name simpleName; - - public GeneratedPackageElement(String qualifiedName) { - super(Collections. emptySet()); - this.qualifiedName = CodeNames.of(qualifiedName); - int lastIndex = qualifiedName.lastIndexOf('.'); - if (lastIndex == -1) { - simpleName = CodeNames.of(""); - } else { - simpleName = CodeNames.of(qualifiedName.substring(lastIndex, qualifiedName.length())); - } - } - - public TypeMirror asType() { - throw new UnsupportedOperationException(); - } - - public ElementKind getKind() { - return ElementKind.PACKAGE; - } - - public R accept(ElementVisitor v, P p) { - return v.visitPackage(this, p); - } - - public Name getQualifiedName() { - return qualifiedName; - } - - public Name getSimpleName() { - return simpleName; - } - - public boolean isUnnamed() { - return simpleName.toString().equals(""); - } - - @Override - public int hashCode() { - return qualifiedName.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PackageElement) { - return qualifiedName.equals(((PackageElement) obj).getQualifiedName()); - } - return super.equals(obj); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeElement.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; - -public final class GeneratedTypeElement extends CodeTypeElement { - - public GeneratedTypeElement(Set modifiers, ElementKind kind, PackageElement packageElement, String simpleName) { - super(modifiers, kind, packageElement, simpleName); - setEnclosingElement(packageElement); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeMirror.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeMirror.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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.dsl.processor.java.model; - -import java.util.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; - -public final class GeneratedTypeMirror extends DeclaredCodeTypeMirror { - - public GeneratedTypeMirror(String packageName, String name) { - super(new GeneratedTypeElement(Collections. emptySet(), ElementKind.CLASS, new GeneratedPackageElement(packageName), name)); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,765 +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.dsl.processor.java.transform; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; - -import java.io.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public abstract class AbstractCodeWriter extends CodeElementScanner { - - private static final int MAX_LINE_LENGTH = Integer.MAX_VALUE; // line wrapping disabled - private static final int LINE_WRAP_INDENTS = 3; - private static final String IDENT_STRING = " "; - private static final String LN = "\n"; /* unix style */ - - protected Writer writer; - private int indent; - private boolean newLine; - private int lineLength; - private boolean lineWrapping = false; - - private OrganizedImports imports; - - protected abstract Writer createWriter(CodeTypeElement clazz) throws IOException; - - @Override - public Void visitType(CodeTypeElement e, Void p) { - if (e.isTopLevelClass()) { - Writer w = null; - try { - imports = OrganizedImports.organize(e); - w = new TrimTrailingSpaceWriter(createWriter(e)); - writer = w; - writeRootClass(e); - } catch (IOException ex) { - throw new RuntimeException(ex); - } finally { - if (w != null) { - try { - w.close(); - } catch (Throwable e1) { - // see eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=361378 - // TODO temporary suppress errors on close. - } - } - writer = null; - } - } else { - writeClassImpl(e); - } - return null; - } - - private void writeRootClass(CodeTypeElement e) { - writeHeader(); - write("package ").write(e.getPackageName()).write(";").writeLn(); - writeEmptyLn(); - - Set generateImports = imports.generateImports(); - List typeImports = new ArrayList<>(); - List staticImports = new ArrayList<>(); - - for (CodeImport codeImport : generateImports) { - if (codeImport.isStaticImport()) { - staticImports.add(codeImport); - } else { - typeImports.add(codeImport); - } - } - Collections.sort(typeImports); - Collections.sort(staticImports); - - for (CodeImport imp : staticImports) { - imp.accept(this, null); - writeLn(); - } - if (!staticImports.isEmpty()) { - writeEmptyLn(); - } - - for (CodeImport imp : typeImports) { - imp.accept(this, null); - writeLn(); - } - if (!typeImports.isEmpty()) { - writeEmptyLn(); - } - - writeClassImpl(e); - } - - private String useImport(Element enclosedType, TypeMirror type) { - if (imports != null) { - return imports.createTypeReference(enclosedType, type); - } else { - return ElementUtils.getSimpleName(type); - } - } - - private void writeClassImpl(CodeTypeElement e) { - for (AnnotationMirror annotation : e.getAnnotationMirrors()) { - visitAnnotation(e, annotation); - writeLn(); - } - - writeModifiers(e.getModifiers(), true); - if (e.getKind() == ElementKind.ENUM) { - write("enum "); - } else { - write("class "); - } - write(e.getSimpleName()); - if (e.getSuperclass() != null && !getQualifiedName(e.getSuperclass()).equals("java.lang.Object")) { - write(" extends ").write(useImport(e, e.getSuperclass())); - } - if (e.getImplements().size() > 0) { - write(" implements "); - for (int i = 0; i < e.getImplements().size(); i++) { - write(useImport(e, e.getImplements().get(i))); - if (i < e.getImplements().size() - 1) { - write(", "); - } - } - } - - write(" {").writeLn(); - writeEmptyLn(); - indent(1); - - List staticFields = getStaticFields(e); - List instanceFields = getInstanceFields(e); - - for (int i = 0; i < staticFields.size(); i++) { - VariableElement field = staticFields.get(i); - field.accept(this, null); - if (e.getKind() == ElementKind.ENUM && i < staticFields.size() - 1) { - write(","); - writeLn(); - } else { - write(";"); - writeLn(); - } - } - - if (staticFields.size() > 0) { - writeEmptyLn(); - } - - for (VariableElement field : instanceFields) { - field.accept(this, null); - write(";"); - writeLn(); - } - if (instanceFields.size() > 0) { - writeEmptyLn(); - } - - for (ExecutableElement method : ElementFilter.constructorsIn(e.getEnclosedElements())) { - method.accept(this, null); - } - - for (ExecutableElement method : getInstanceMethods(e)) { - method.accept(this, null); - } - - for (ExecutableElement method : getStaticMethods(e)) { - method.accept(this, null); - } - - for (TypeElement clazz : e.getInnerClasses()) { - clazz.accept(this, null); - } - - dedent(1); - write("}"); - writeEmptyLn(); - } - - private static List getStaticFields(CodeTypeElement clazz) { - List staticFields = new ArrayList<>(); - for (VariableElement field : clazz.getFields()) { - if (field.getModifiers().contains(Modifier.STATIC)) { - staticFields.add(field); - } - } - return staticFields; - } - - private static List getInstanceFields(CodeTypeElement clazz) { - List instanceFields = new ArrayList<>(); - for (VariableElement field : clazz.getFields()) { - if (!field.getModifiers().contains(Modifier.STATIC)) { - instanceFields.add(field); - } - } - return instanceFields; - } - - private static List getStaticMethods(CodeTypeElement clazz) { - List staticMethods = new ArrayList<>(); - for (ExecutableElement method : clazz.getMethods()) { - if (method.getModifiers().contains(Modifier.STATIC)) { - staticMethods.add(method); - } - } - return staticMethods; - } - - private static List getInstanceMethods(CodeTypeElement clazz) { - List instanceMethods = new ArrayList<>(); - for (ExecutableElement method : clazz.getMethods()) { - if (!method.getModifiers().contains(Modifier.STATIC)) { - instanceMethods.add(method); - } - } - return instanceMethods; - } - - @Override - public Void visitVariable(VariableElement f, Void p) { - Element parent = f.getEnclosingElement(); - - for (AnnotationMirror annotation : f.getAnnotationMirrors()) { - visitAnnotation(f, annotation); - write(" "); - } - - CodeTree init = null; - if (f instanceof CodeVariableElement) { - init = ((CodeVariableElement) f).getInit(); - } - - if (parent != null && parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) { - write(f.getSimpleName()); - if (init != null) { - write("("); - visitTree(init, p, f); - write(")"); - } - } else { - writeModifiers(f.getModifiers(), true); - - boolean varArgs = false; - if (parent != null && parent.getKind() == ElementKind.METHOD) { - ExecutableElement method = (ExecutableElement) parent; - if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) { - varArgs = true; - } - } - - TypeMirror varType = f.asType(); - if (varArgs) { - if (varType.getKind() == TypeKind.ARRAY) { - varType = ((ArrayType) varType).getComponentType(); - } - write(useImport(f, varType)); - write("..."); - } else { - write(useImport(f, varType)); - } - - write(" "); - write(f.getSimpleName()); - if (init != null) { - write(" = "); - visitTree(init, p, f); - } - } - return null; - } - - private void visitAnnotation(Element enclosedElement, AnnotationMirror e) { - write("@").write(useImport(enclosedElement, e.getAnnotationType())); - - if (!e.getElementValues().isEmpty()) { - write("("); - final ExecutableElement defaultElement = findExecutableElement(e.getAnnotationType(), "value"); - - Map values = e.getElementValues(); - if (defaultElement != null && values.size() == 1 && values.get(defaultElement) != null) { - visitAnnotationValue(enclosedElement, values.get(defaultElement)); - } else { - Set methodsSet = values.keySet(); - List methodsList = new ArrayList<>(); - for (ExecutableElement method : methodsSet) { - if (values.get(method) == null) { - continue; - } - methodsList.add(method); - } - - Collections.sort(methodsList, new Comparator() { - - @Override - public int compare(ExecutableElement o1, ExecutableElement o2) { - return o1.getSimpleName().toString().compareTo(o2.getSimpleName().toString()); - } - }); - - for (int i = 0; i < methodsList.size(); i++) { - ExecutableElement method = methodsList.get(i); - AnnotationValue value = values.get(method); - write(method.getSimpleName().toString()); - write(" = "); - visitAnnotationValue(enclosedElement, value); - - if (i < methodsList.size() - 1) { - write(", "); - } - } - } - - write(")"); - } - } - - private void visitAnnotationValue(Element enclosedElement, AnnotationValue e) { - e.accept(new AnnotationValueWriterVisitor(enclosedElement), null); - } - - private class AnnotationValueWriterVisitor extends AbstractAnnotationValueVisitor7 { - - private final Element enclosedElement; - - public AnnotationValueWriterVisitor(Element enclosedElement) { - this.enclosedElement = enclosedElement; - } - - @Override - public Void visitBoolean(boolean b, Void p) { - write(Boolean.toString(b)); - return null; - } - - @Override - public Void visitByte(byte b, Void p) { - write(Byte.toString(b)); - return null; - } - - @Override - public Void visitChar(char c, Void p) { - write(Character.toString(c)); - return null; - } - - @Override - public Void visitDouble(double d, Void p) { - write(Double.toString(d)); - return null; - } - - @Override - public Void visitFloat(float f, Void p) { - write(Float.toString(f)); - return null; - } - - @Override - public Void visitInt(int i, Void p) { - write(Integer.toString(i)); - return null; - } - - @Override - public Void visitLong(long i, Void p) { - write(Long.toString(i)); - return null; - } - - @Override - public Void visitShort(short s, Void p) { - write(Short.toString(s)); - return null; - } - - @Override - public Void visitString(String s, Void p) { - write("\""); - write(s); - write("\""); - return null; - } - - @Override - public Void visitType(TypeMirror t, Void p) { - write(useImport(enclosedElement, t)); - write(".class"); - return null; - } - - @Override - public Void visitEnumConstant(VariableElement c, Void p) { - write(useImport(enclosedElement, c.asType())); - write("."); - write(c.getSimpleName().toString()); - return null; - } - - @Override - public Void visitAnnotation(AnnotationMirror a, Void p) { - AbstractCodeWriter.this.visitAnnotation(enclosedElement, a); - return null; - } - - @Override - public Void visitArray(List vals, Void p) { - write("{"); - for (int i = 0; i < vals.size(); i++) { - AnnotationValue value = vals.get(i); - AbstractCodeWriter.this.visitAnnotationValue(enclosedElement, value); - if (i < vals.size() - 1) { - write(", "); - } - } - write("}"); - return null; - } - } - - private static ExecutableElement findExecutableElement(DeclaredType type, String name) { - List elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); - for (ExecutableElement executableElement : elements) { - if (executableElement.getSimpleName().toString().equals(name)) { - return executableElement; - } - } - return null; - } - - @Override - public void visitImport(CodeImport e, Void p) { - write("import "); - if (e.isStaticImport()) { - write("static "); - } - write(e.getPackageName()); - write("."); - write(e.getSymbolName()); - write(";"); - } - - @Override - public Void visitExecutable(CodeExecutableElement e, Void p) { - for (AnnotationMirror annotation : e.getAnnotationMirrors()) { - visitAnnotation(e, annotation); - writeLn(); - } - - writeModifiers(e.getModifiers(), !e.getEnclosingClass().getModifiers().contains(Modifier.FINAL)); - - if (e.getReturnType() != null) { - write(useImport(e, e.getReturnType())); - write(" "); - } - write(e.getSimpleName()); - write("("); - - for (int i = 0; i < e.getParameters().size(); i++) { - VariableElement param = e.getParameters().get(i); - param.accept(this, p); - if (i < e.getParameters().size() - 1) { - write(", "); - } - } - write(")"); - - List throwables = e.getThrownTypes(); - if (throwables.size() > 0) { - write(" throws "); - for (int i = 0; i < throwables.size(); i++) { - write(useImport(e, throwables.get(i))); - if (i < throwables.size() - 1) { - write(", "); - } - } - } - - if (e.getModifiers().contains(Modifier.ABSTRACT)) { - writeLn(";"); - } else if (e.getBodyTree() != null) { - writeLn(" {"); - indent(1); - visitTree(e.getBodyTree(), p, e); - dedent(1); - writeLn("}"); - } else if (e.getBody() != null) { - write(" {"); - write(e.getBody()); - writeLn("}"); - } else { - writeLn(" {"); - writeLn("}"); - } - writeEmptyLn(); - return null; - } - - @Override - public void visitTree(CodeTree e, Void p, Element enclosingElement) { - CodeTreeKind kind = e.getCodeKind(); - - switch (kind) { - case COMMA_GROUP: - List children = e.getEnclosedElements(); - if (children != null) { - for (int i = 0; i < children.size(); i++) { - visitTree(children.get(i), p, enclosingElement); - if (i < e.getEnclosedElements().size() - 1) { - write(", "); - } - } - } - break; - case GROUP: - super.visitTree(e, p, enclosingElement); - break; - case INDENT: - indent(1); - super.visitTree(e, p, enclosingElement); - dedent(1); - break; - case NEW_LINE: - writeLn(); - break; - case STRING: - if (e.getString() != null) { - write(e.getString()); - } else { - write("null"); - } - break; - case STATIC_FIELD_REFERENCE: - if (e.getString() != null) { - write(imports.createStaticFieldReference(enclosingElement, e.getType(), e.getString())); - } else { - write("null"); - } - break; - case STATIC_METHOD_REFERENCE: - if (e.getString() != null) { - write(imports.createStaticMethodReference(enclosingElement, e.getType(), e.getString())); - } else { - write("null"); - } - break; - case TYPE: - write(useImport(enclosingElement, e.getType())); - break; - default: - assert false; - return; - } - } - - protected void writeHeader() { - // default implementation does nothing - } - - private void writeModifiers(Set modifiers, boolean includeFinal) { - if (modifiers != null && !modifiers.isEmpty()) { - Modifier[] modArray = modifiers.toArray(new Modifier[modifiers.size()]); - Arrays.sort(modArray); - for (Modifier mod : modArray) { - if (mod == Modifier.FINAL && !includeFinal) { - continue; - } - write(mod.toString()); - write(" "); - } - } - } - - private void indent(int count) { - indent += count; - } - - private void dedent(int count) { - indent -= count; - } - - private void writeLn() { - writeLn(""); - } - - protected void writeLn(String text) { - write(text); - write(LN); - lineLength = 0; - newLine = true; - if (lineWrapping) { - dedent(LINE_WRAP_INDENTS); - lineWrapping = false; - } - lineWrapping = false; - } - - private void writeEmptyLn() { - writeLn(); - } - - private AbstractCodeWriter write(Name name) { - return write(name.toString()); - } - - private AbstractCodeWriter write(String m) { - if (m.isEmpty()) { - return this; - } - try { - String s = m; - lineLength += s.length(); - if (newLine && s != LN) { - writeIndent(); - newLine = false; - } - if (lineLength > MAX_LINE_LENGTH) { - s = wrapLine(s); - } - writer.write(s); - } catch (IOException e) { - throw new RuntimeException(e); - } - return this; - } - - private String wrapLine(String m) throws IOException { - assert !m.isEmpty(); - - char firstCharacter = m.charAt(0); - char lastCharacter = m.charAt(m.length() - 1); - if (firstCharacter == '\"' && lastCharacter == '\"') { - // string line wrapping - String string = m.substring(1, m.length() - 1); - if (string.isEmpty()) { - return m; - } - - // restore original line length - lineLength = lineLength - m.length(); - int size = 0; - for (int i = 0; i < string.length(); i += size) { - if (i != 0) { - write("+ "); - } - - int nextSize = MAX_LINE_LENGTH - lineLength - 2; - if (nextSize <= 0) { - writeLn(); - nextSize = MAX_LINE_LENGTH - lineLength - 2; - } - - int end = Math.min(i + nextSize, string.length()); - - // TODO(CH): fails in normal usage - output ok though - // assert lineLength + (end - i) + 2 < MAX_LINE_LENGTH; - write("\""); - write(string.substring(i, end)); - write("\""); - size = nextSize; - } - - return ""; - } else if (!Character.isAlphabetic(firstCharacter) && firstCharacter != '+') { - return m; - } - - if (!lineWrapping) { - indent(LINE_WRAP_INDENTS); - } - lineWrapping = true; - lineLength = 0; - write(LN); - writeIndent(); - return m; - } - - private void writeIndent() throws IOException { - lineLength += indentSize(); - for (int i = 0; i < indent; i++) { - writer.write(IDENT_STRING); - } - } - - private int indentSize() { - return IDENT_STRING.length() * indent; - } - - private static class TrimTrailingSpaceWriter extends Writer { - - private final Writer delegate; - private final StringBuilder buffer = new StringBuilder(); - - public TrimTrailingSpaceWriter(Writer delegate) { - this.delegate = delegate; - } - - @Override - public void close() throws IOException { - this.delegate.close(); - } - - @Override - public void flush() throws IOException { - this.delegate.flush(); - } - - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - buffer.append(cbuf, off, len); - int newLinePoint = buffer.indexOf(LN); - - if (newLinePoint != -1) { - String lhs = trimTrailing(buffer.substring(0, newLinePoint)); - delegate.write(lhs); - delegate.write(LN); - buffer.delete(0, newLinePoint + 1); - } - } - - private static String trimTrailing(String s) { - int cut = 0; - for (int i = s.length() - 1; i >= 0; i--) { - if (Character.isWhitespace(s.charAt(i))) { - cut++; - } else { - break; - } - } - if (cut > 0) { - return s.substring(0, s.length() - cut); - } - return s; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +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.dsl.processor.java.transform; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.io.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public class FixWarningsVisitor extends CodeElementScanner { - - private final Set symbolsUsed = new HashSet<>(); - - private final ProcessingEnvironment processingEnv; - private final DeclaredType unusedAnnotation; - private final DeclaredType overrideType; - - public FixWarningsVisitor(ProcessingEnvironment processingEnv, DeclaredType unusedAnnotation, DeclaredType overrideType) { - this.processingEnv = processingEnv; - this.unusedAnnotation = unusedAnnotation; - this.overrideType = overrideType; - } - - @Override - public Void visitType(CodeTypeElement e, Void p) { - List superTypes = ElementUtils.getSuperTypes(e); - for (TypeElement type : superTypes) { - String qualifiedName = ElementUtils.getQualifiedName(type); - if (qualifiedName.equals(Serializable.class.getCanonicalName())) { - if (!e.containsField("serialVersionUID")) { - e.add(new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), ElementUtils.getType(processingEnv, long.class), "serialVersionUID", "1L")); - } - break; - } - } - - return super.visitType(e, p); - } - - @Override - public Void visitExecutable(CodeExecutableElement e, Void p) { - if (e.getParameters().isEmpty()) { - return null; - } else if (e.getModifiers().contains(Modifier.ABSTRACT)) { - return null; - } else if (containsOverride(e)) { - return null; - } - - symbolsUsed.clear(); - super.visitExecutable(e, p); - - for (VariableElement parameter : e.getParameters()) { - if (!symbolsUsed.contains(parameter.getSimpleName().toString())) { - e.getAnnotationMirrors().add(createUnusedAnnotationMirror()); - break; - } - } - return null; - } - - private boolean containsOverride(CodeExecutableElement e) { - for (AnnotationMirror mirror : e.getAnnotationMirrors()) { - if (ElementUtils.typeEquals(overrideType, mirror.getAnnotationType())) { - return true; - } - } - return false; - } - - private CodeAnnotationMirror createUnusedAnnotationMirror() { - CodeAnnotationMirror mirror = new CodeAnnotationMirror(unusedAnnotation); - mirror.setElementValue(mirror.findExecutableElement("value"), new CodeAnnotationValue("unused")); - return mirror; - } - - @Override - public void visitTree(CodeTree e, Void p, Element enclosingElement) { - if (e.getString() != null) { - computeSymbols(e.getString()); - } - super.visitTree(e, p, enclosingElement); - } - - private void computeSymbols(String s) { - // TODO there should not be any need for a StringTokenizer if we have a real AST for - // method bodies. Also the current solution is not perfect. What if one token - // is spread across multiple CodeTree instances? But for now that works. - StringTokenizer tokenizer = new StringTokenizer(s, ".= :,()[];{}\"\"'' ", false); - while (tokenizer.hasMoreElements()) { - String token = tokenizer.nextToken().trim(); - if (token.length() > 0) { - symbolsUsed.add(token); - } - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/GenerateOverrideVisitor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/GenerateOverrideVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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.dsl.processor.java.transform; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public class GenerateOverrideVisitor extends CodeElementScanner { - - private final DeclaredType overrideType; - - public GenerateOverrideVisitor(DeclaredType overrideType) { - this.overrideType = overrideType; - } - - @Override - public Void visitExecutable(CodeExecutableElement e, Void p) { - if (!e.getModifiers().contains(Modifier.STATIC) && !e.getModifiers().contains(Modifier.PRIVATE)) { - String name = e.getSimpleName().toString(); - TypeMirror[] params = e.getParameterTypes(); - - for (AnnotationMirror mirror : e.getAnnotationMirrors()) { - if (ElementUtils.typeEquals(overrideType, mirror.getAnnotationType())) { - // already declared (may happen if method copied from super class) - return super.visitExecutable(e, p); - } - } - - if (isDeclaredMethodInSuperType(e.getEnclosingClass(), name, params)) { - e.addAnnotationMirror(new CodeAnnotationMirror(overrideType)); - } - } - return super.visitExecutable(e, p); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,452 +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.dsl.processor.java.transform; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -public final class OrganizedImports { - - private final Map classImportUsage = new HashMap<>(); - private final Map> autoImportCache = new HashMap<>(); - - private final CodeTypeElement topLevelClass; - - private OrganizedImports(CodeTypeElement topLevelClass) { - this.topLevelClass = topLevelClass; - } - - public static OrganizedImports organize(CodeTypeElement topLevelClass) { - OrganizedImports organized = new OrganizedImports(topLevelClass); - organized.organizeImpl(); - return organized; - } - - private void organizeImpl() { - ImportTypeReferenceVisitor reference = new ImportTypeReferenceVisitor(); - topLevelClass.accept(reference, null); - } - - public String createTypeReference(Element enclosedElement, TypeMirror type) { - switch (type.getKind()) { - case BOOLEAN: - case BYTE: - case CHAR: - case DOUBLE: - case FLOAT: - case SHORT: - case INT: - case LONG: - case VOID: - return ElementUtils.getSimpleName(type); - case DECLARED: - return createDeclaredTypeName(enclosedElement, (DeclaredType) type); - case ARRAY: - return createTypeReference(enclosedElement, ((ArrayType) type).getComponentType()) + "[]"; - case WILDCARD: - return createWildcardName(enclosedElement, (WildcardType) type); - case TYPEVAR: - return "?"; - default: - throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type); - } - } - - public String createStaticFieldReference(Element enclosedElement, TypeMirror type, String fieldName) { - return createStaticReference(enclosedElement, type, fieldName); - } - - public String createStaticMethodReference(Element enclosedElement, TypeMirror type, String methodName) { - return createStaticReference(enclosedElement, type, methodName); - } - - private String createStaticReference(Element enclosedElement, TypeMirror type, String name) { - // ambiguous import - return createTypeReference(enclosedElement, type) + "." + name; - } - - private String createWildcardName(Element enclosedElement, WildcardType type) { - StringBuilder b = new StringBuilder(); - if (type.getExtendsBound() != null) { - b.append("? extends ").append(createTypeReference(enclosedElement, type.getExtendsBound())); - } else if (type.getSuperBound() != null) { - b.append("? super ").append(createTypeReference(enclosedElement, type.getExtendsBound())); - } else { - b.append("?"); - } - return b.toString(); - } - - private String createDeclaredTypeName(Element enclosedElement, DeclaredType type) { - String name = ElementUtils.fixECJBinaryNameIssue(type.asElement().getSimpleName().toString()); - if (classImportUsage.containsKey(name)) { - String qualifiedImport = classImportUsage.get(name); - String qualifiedName = ElementUtils.getEnclosedQualifiedName(type); - - if (!qualifiedName.equals(qualifiedImport)) { - name = qualifiedName; - } - } - - List genericTypes = type.getTypeArguments(); - if (genericTypes.size() == 0) { - return name; - } - - StringBuilder b = new StringBuilder(name); - b.append("<"); - for (int i = 0; i < genericTypes.size(); i++) { - TypeMirror genericType = i < genericTypes.size() ? genericTypes.get(i) : null; - if (genericType != null) { - b.append(createTypeReference(enclosedElement, genericType)); - } else { - b.append("?"); - } - - if (i < genericTypes.size() - 1) { - b.append(", "); - } - } - b.append(">"); - return b.toString(); - } - - public Set generateImports() { - Set imports = new HashSet<>(); - - imports.addAll(generateImports(classImportUsage)); - - return imports; - } - - private boolean needsImport(Element enclosed, TypeMirror importType) { - String importPackagName = getPackageName(importType); - TypeElement enclosedElement = findNearestEnclosingType(enclosed); - if (importPackagName == null) { - return false; - } else if (importPackagName.equals("java.lang")) { - return false; - } else if (importPackagName.equals(getPackageName(topLevelClass)) && ElementUtils.isTopLevelClass(importType)) { - return false; // same package name -> no import - } - - String enclosedElementId = ElementUtils.getUniqueIdentifier(enclosedElement.asType()); - Set autoImportedTypes = autoImportCache.get(enclosedElementId); - if (autoImportedTypes == null) { - List elements = ElementUtils.getElementHierarchy(enclosedElement); - autoImportedTypes = new HashSet<>(); - for (Element element : elements) { - if (element.getKind().isClass()) { - collectSuperTypeImports((TypeElement) element, autoImportedTypes); - collectInnerTypeImports((TypeElement) element, autoImportedTypes); - } - } - autoImportCache.put(enclosedElementId, autoImportedTypes); - } - - String qualifiedName = getQualifiedName(importType); - if (autoImportedTypes.contains(qualifiedName)) { - return false; - } - - return true; - } - - private static Set generateImports(Map symbols) { - TreeSet importObjects = new TreeSet<>(); - for (String symbol : symbols.keySet()) { - String packageName = symbols.get(symbol); - if (packageName != null) { - importObjects.add(new CodeImport(packageName, symbol, false)); - } - } - return importObjects; - } - - private static void collectInnerTypeImports(TypeElement e, Set autoImportedTypes) { - autoImportedTypes.add(getQualifiedName(e)); - for (TypeElement innerClass : ElementFilter.typesIn(e.getEnclosedElements())) { - collectInnerTypeImports(innerClass, autoImportedTypes); - } - } - - private static void collectSuperTypeImports(TypeElement e, Set autoImportedTypes) { - List superTypes = getSuperTypes(e); - for (TypeElement superType : superTypes) { - List declaredTypes = getDeclaredTypes(superType); - for (TypeElement declaredType : declaredTypes) { - if (!superTypes.contains(declaredType)) { - autoImportedTypes.add(getQualifiedName(declaredType)); - } - } - } - } - - private abstract static class TypeReferenceVisitor extends CodeElementScanner { - - @Override - public void visitTree(CodeTree e, Void p, Element enclosing) { - if (e.getCodeKind() == CodeTreeKind.STATIC_FIELD_REFERENCE) { - visitStaticFieldReference(enclosing, e.getType(), e.getString()); - } else if (e.getCodeKind() == CodeTreeKind.STATIC_METHOD_REFERENCE) { - visitStaticMethodReference(enclosing, e.getType(), e.getString()); - } else if (e.getType() != null) { - visitTypeReference(enclosing, e.getType()); - } - super.visitTree(e, p, enclosing); - } - - @Override - public Void visitExecutable(CodeExecutableElement e, Void p) { - visitAnnotations(e, e.getAnnotationMirrors()); - if (e.getReturnType() != null) { - visitTypeReference(e, e.getReturnType()); - } - for (TypeMirror type : e.getThrownTypes()) { - visitTypeReference(e, type); - } - return super.visitExecutable(e, p); - } - - @Override - public Void visitType(CodeTypeElement e, Void p) { - visitAnnotations(e, e.getAnnotationMirrors()); - - visitTypeReference(e, e.getSuperclass()); - for (TypeMirror type : e.getImplements()) { - visitTypeReference(e, type); - } - - return super.visitType(e, p); - } - - private void visitAnnotations(Element enclosingElement, List mirrors) { - for (AnnotationMirror mirror : mirrors) { - visitAnnotation(enclosingElement, mirror); - } - } - - public void visitAnnotation(Element enclosingElement, AnnotationMirror e) { - visitTypeReference(enclosingElement, e.getAnnotationType()); - if (!e.getElementValues().isEmpty()) { - Map values = e.getElementValues(); - Set methodsSet = values.keySet(); - List methodsList = new ArrayList<>(); - for (ExecutableElement method : methodsSet) { - if (values.get(method) == null) { - continue; - } - methodsList.add(method); - } - - for (int i = 0; i < methodsList.size(); i++) { - AnnotationValue value = values.get(methodsList.get(i)); - visitAnnotationValue(enclosingElement, value); - } - } - } - - public void visitAnnotationValue(Element enclosingElement, AnnotationValue e) { - e.accept(new AnnotationValueReferenceVisitor(enclosingElement), null); - } - - private class AnnotationValueReferenceVisitor extends AbstractAnnotationValueVisitor7 { - - private final Element enclosingElement; - - public AnnotationValueReferenceVisitor(Element enclosedElement) { - this.enclosingElement = enclosedElement; - } - - @Override - public Void visitBoolean(boolean b, Void p) { - return null; - } - - @Override - public Void visitByte(byte b, Void p) { - return null; - } - - @Override - public Void visitChar(char c, Void p) { - return null; - } - - @Override - public Void visitDouble(double d, Void p) { - return null; - } - - @Override - public Void visitFloat(float f, Void p) { - return null; - } - - @Override - public Void visitInt(int i, Void p) { - return null; - } - - @Override - public Void visitLong(long i, Void p) { - return null; - } - - @Override - public Void visitShort(short s, Void p) { - return null; - } - - @Override - public Void visitString(String s, Void p) { - return null; - } - - @Override - public Void visitType(TypeMirror t, Void p) { - visitTypeReference(enclosingElement, t); - return null; - } - - @Override - public Void visitEnumConstant(VariableElement c, Void p) { - visitTypeReference(enclosingElement, c.asType()); - return null; - } - - @Override - public Void visitAnnotation(AnnotationMirror a, Void p) { - TypeReferenceVisitor.this.visitAnnotation(enclosingElement, a); - return null; - } - - @Override - public Void visitArray(List vals, Void p) { - for (int i = 0; i < vals.size(); i++) { - TypeReferenceVisitor.this.visitAnnotationValue(enclosingElement, vals.get(i)); - } - return null; - } - } - - @Override - public Void visitVariable(VariableElement f, Void p) { - visitAnnotations(f, f.getAnnotationMirrors()); - visitTypeReference(f, f.asType()); - return super.visitVariable(f, p); - } - - @Override - public void visitImport(CodeImport e, Void p) { - } - - public abstract void visitTypeReference(Element enclosedType, TypeMirror type); - - public abstract void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName); - - public abstract void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName); - - } - - private class ImportTypeReferenceVisitor extends TypeReferenceVisitor { - - @Override - public void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName) { - visitTypeReference(enclosedType, type); - } - - @Override - public void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName) { - visitTypeReference(enclosedType, type); - } - - @Override - public void visitTypeReference(Element enclosedType, TypeMirror type) { - if (type != null) { - switch (type.getKind()) { - case BOOLEAN: - case BYTE: - case CHAR: - case DOUBLE: - case FLOAT: - case SHORT: - case INT: - case LONG: - case VOID: - return; - case DECLARED: - if (needsImport(enclosedType, type)) { - DeclaredType declard = (DeclaredType) type; - registerSymbol(classImportUsage, ElementUtils.getEnclosedQualifiedName(declard), ElementUtils.getDeclaredName(declard, false)); - } - for (TypeMirror argument : ((DeclaredType) type).getTypeArguments()) { - visitTypeReference(enclosedType, argument); - } - return; - case ARRAY: - visitTypeReference(enclosedType, ((ArrayType) type).getComponentType()); - return; - case WILDCARD: - WildcardType wildcard = (WildcardType) type; - if (wildcard.getExtendsBound() != null) { - visitTypeReference(enclosedType, wildcard.getExtendsBound()); - } else if (wildcard.getSuperBound() != null) { - visitTypeReference(enclosedType, wildcard.getSuperBound()); - } - return; - case TYPEVAR: - return; - default: - throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type); - } - - } - } - - private void registerSymbol(Map symbolUsage, String elementQualifiedName, String elementName) { - if (symbolUsage.containsKey(elementName)) { - String otherQualifiedName = symbolUsage.get(elementName); - if (otherQualifiedName == null) { - // already registered ambiguous - return; - } - if (!otherQualifiedName.equals(elementQualifiedName)) { - symbolUsage.put(elementName, null); - } - } else { - symbolUsage.put(elementName, elementQualifiedName); - } - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/AnnotatedParameterSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/AnnotatedParameterSpec.java Wed Jun 17 10:01:47 2015 +0200 +++ /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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public final class AnnotatedParameterSpec extends ParameterSpec { - - private final DeclaredType annotationType; - - public AnnotatedParameterSpec(DeclaredType type) { - super("annotated", Collections. emptyList()); - this.annotationType = type; - } - - public DeclaredType getAnnotationType() { - return annotationType; - } - - @Override - public boolean isAnnotated() { - return true; - } - - @Override - public boolean matches(VariableElement variable) { - if (ElementUtils.findAnnotationMirror(variable.getAnnotationMirrors(), annotationType) != null) { - return true; - } - return false; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/AssumptionExpression.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/AssumptionExpression.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.java.*; - -public final class AssumptionExpression extends MessageContainer { - - private final TemplateMethod source; - private final DSLExpression expression; - private final String id; - - public AssumptionExpression(TemplateMethod source, DSLExpression expression, String id) { - this.source = source; - this.expression = expression; - this.id = id; - } - - public String getId() { - return id; - } - - @Override - public Element getMessageElement() { - return source.getMessageElement(); - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return source.getMessageAnnotation(); - } - - @Override - public AnnotationValue getMessageAnnotationValue() { - return ElementUtils.getAnnotationValue(getMessageAnnotation(), "assumptions"); - } - - public DSLExpression getExpression() { - return expression; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/CacheExpression.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/CacheExpression.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.java.*; - -public final class CacheExpression extends MessageContainer { - - private final DSLExpression expression; - private final Parameter sourceParameter; - private final AnnotationMirror sourceAnnotationMirror; - - public CacheExpression(Parameter sourceParameter, AnnotationMirror sourceAnnotationMirror, DSLExpression expression) { - this.sourceParameter = sourceParameter; - this.expression = expression; - this.sourceAnnotationMirror = sourceAnnotationMirror; - } - - public Parameter getParameter() { - return sourceParameter; - } - - @Override - public Element getMessageElement() { - return sourceParameter.getVariableElement(); - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return sourceAnnotationMirror; - } - - @Override - public AnnotationValue getMessageAnnotationValue() { - return ElementUtils.getAnnotationValue(getMessageAnnotation(), "value"); - } - - public DSLExpression getExpression() { - return expression; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/CreateCastData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/CreateCastData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import java.util.*; - -public class CreateCastData extends TemplateMethod { - - private final List childNames; - - public CreateCastData(TemplateMethod method, List childNames) { - super(method); - this.childNames = childNames; - } - - public List getChildNames() { - return childNames; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ExecutableTypeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ExecutableTypeData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; - -public class ExecutableTypeData extends MessageContainer implements Comparable { - - private final NodeData node; - private final ExecutableElement method; - private final TypeMirror returnType; - private final TypeMirror frameParameter; - private final List evaluatedParameters; - private ExecutableTypeData delegatedTo; - private final List delegatedFrom = new ArrayList<>(); - - private String uniqueName; - - public ExecutableTypeData(NodeData node, TypeMirror returnType, String uniqueName, TypeMirror frameParameter, List evaluatedParameters) { - this.node = node; - this.returnType = returnType; - this.frameParameter = frameParameter; - this.evaluatedParameters = evaluatedParameters; - this.uniqueName = uniqueName; - this.method = null; - } - - public ExecutableTypeData(NodeData node, ExecutableElement method, int signatureSize, List frameTypes) { - this.node = node; - this.method = method; - this.returnType = method.getReturnType(); - TypeMirror foundFrameParameter = null; - List parameters = method.getParameters(); - - int parameterIndex = 0; - evaluatedParameters = new ArrayList<>(); - if (!parameters.isEmpty()) { - TypeMirror firstParameter = parameters.get(0).asType(); - for (TypeMirror frameType : frameTypes) { - if (ElementUtils.typeEquals(firstParameter, frameType)) { - foundFrameParameter = firstParameter; - parameterIndex++; - break; - } - } - } - - int numberParameters = Math.max(parameters.size() - parameterIndex, signatureSize); - for (int i = 0; i < numberParameters; i++) { - TypeMirror parameter; - if (method.isVarArgs() && parameterIndex >= parameters.size() - 1) { - ArrayType varArgsArray = (ArrayType) parameters.get(parameters.size() - 1).asType(); - parameter = varArgsArray.getComponentType(); - } else if (parameterIndex < parameters.size()) { - parameter = parameters.get(parameterIndex).asType(); - } else { - break; - } - parameterIndex++; - evaluatedParameters.add(parameter); - } - this.frameParameter = foundFrameParameter; - this.uniqueName = createName(this); - } - - public static String createName(ExecutableTypeData type) { - return "execute" + (ElementUtils.isObject(type.getReturnType()) ? "" : ElementUtils.getTypeId(type.getReturnType())); - } - - public void addDelegatedFrom(ExecutableTypeData child) { - this.delegatedFrom.add(child); - child.delegatedTo = this; - } - - public List getDelegatedFrom() { - return delegatedFrom; - } - - public ExecutableTypeData getDelegatedTo() { - return delegatedTo; - } - - public ExecutableElement getMethod() { - return method; - } - - public String getUniqueName() { - return uniqueName; - } - - public void setUniqueName(String name) { - this.uniqueName = name; - } - - @Override - public Element getMessageElement() { - return method; - } - - public List getEvaluatedParameters() { - return evaluatedParameters; - } - - public List getSignatureParameters() { - List signaturetypes = new ArrayList<>(); - int index = 0; - for (NodeExecutionData execution : node.getChildExecutions()) { - if (execution.isShortCircuit()) { - index++; - } - if (index < getEvaluatedCount()) { - signaturetypes.add(getEvaluatedParameters().get(index)); - } - index++; - } - return signaturetypes; - } - - public int getVarArgsIndex(int parameterIndex) { - if (method.isVarArgs()) { - int index = parameterIndex - (method.getParameters().size() - 1); - return index; - } - return -1; - } - - public int getParameterIndex(int signatureIndex) { - return frameParameter != null ? signatureIndex + 1 : signatureIndex; - } - - public TypeMirror getFrameParameter() { - return frameParameter; - } - - public TypeMirror getReturnType() { - return returnType; - } - - public boolean hasUnexpectedValue(ProcessorContext context) { - return method == null ? false : ElementUtils.canThrowType(method.getThrownTypes(), context.getType(UnexpectedResultException.class)); - } - - public boolean isFinal() { - return method == null ? false : method.getModifiers().contains(Modifier.FINAL); - } - - public boolean isAbstract() { - return method == null ? false : method.getModifiers().contains(Modifier.ABSTRACT); - } - - public int getEvaluatedCount() { - return evaluatedParameters.size(); - } - - public boolean canDelegateTo(ExecutableTypeData to) { - ExecutableTypeData from = this; - if (to.getEvaluatedCount() < from.getEvaluatedCount()) { - return false; - } - - ProcessorContext context = node.getContext(); - - // we cannot delegate from generic to unexpected - if (!from.hasUnexpectedValue(context) && to.hasUnexpectedValue(context)) { - return false; - } - - // we can skip the return type check for void. everything is assignable to void. - if (!isVoid(from.getReturnType())) { - if (!isSubtypeBoxed(context, from.getReturnType(), to.getReturnType()) && !isSubtypeBoxed(context, to.getReturnType(), from.getReturnType())) { - return false; - } - } - if (from.getFrameParameter() != to.getFrameParameter() && from.getFrameParameter() != null && to.getFrameParameter() != null && - !isSubtypeBoxed(context, from.getFrameParameter(), to.getFrameParameter())) { - return false; - } - - for (int i = 0; i < from.getEvaluatedCount(); i++) { - if (!isSubtypeBoxed(context, from.getEvaluatedParameters().get(i), to.getEvaluatedParameters().get(i))) { - return false; - } - } - - List fromSignatureParameters = from.getSignatureParameters(); - List toSignatureParameters = to.getSignatureParameters(); - for (int i = fromSignatureParameters.size(); i < toSignatureParameters.size(); i++) { - TypeMirror delegateToParameter = toSignatureParameters.get(i); - if (i < node.getChildExecutions().size()) { - TypeMirror genericType = node.getGenericType(node.getChildExecutions().get(i)); - if (!isSubtypeBoxed(context, genericType, delegateToParameter)) { - return false; - } - } - } - - return true; - } - - public int compareTo(ExecutableTypeData o2) { - ExecutableTypeData o1 = this; - ProcessorContext context = ProcessorContext.getInstance(); - - if (canDelegateTo(o2)) { - if (!o2.canDelegateTo(this)) { - return 1; - } - } else if (o2.canDelegateTo(this)) { - return -1; - } - - int result = Integer.compare(o2.getEvaluatedCount(), o1.getEvaluatedCount()); - if (result != 0) { - return result; - } - - result = Boolean.compare(o1.hasUnexpectedValue(context), o2.hasUnexpectedValue(context)); - if (result != 0) { - return result; - } - - result = compareType(context, o1.getReturnType(), o2.getReturnType()); - if (result != 0) { - return result; - } - result = compareType(context, o1.getFrameParameter(), o2.getFrameParameter()); - if (result != 0) { - return result; - } - - for (int i = 0; i < o1.getEvaluatedCount(); i++) { - result = compareType(context, o1.getEvaluatedParameters().get(i), o2.getEvaluatedParameters().get(i)); - if (result != 0) { - return result; - } - } - - result = o1.getUniqueName().compareTo(o2.getUniqueName()); - if (result != 0) { - return result; - } - - if (o1.getMethod() != null && o2.getMethod() != null) { - result = ElementUtils.compareMethod(o1.getMethod(), o2.getMethod()); - if (result != 0) { - return result; - } - } - return 0; - } - - public static int compareType(ProcessorContext context, TypeMirror signature1, TypeMirror signature2) { - if (signature1 == null) { - if (signature2 == null) { - return 0; - } - return -1; - } else if (signature2 == null) { - return 1; - } - if (ElementUtils.typeEquals(signature1, signature2)) { - return 0; - } - if (isVoid(signature1)) { - if (isVoid(signature2)) { - return 0; - } - return 1; - } else if (isVoid(signature2)) { - return -1; - } - - TypeMirror boxedType1 = ElementUtils.boxType(context, signature1); - TypeMirror boxedType2 = ElementUtils.boxType(context, signature2); - - if (ElementUtils.isSubtype(boxedType1, boxedType2)) { - if (ElementUtils.isSubtype(boxedType2, boxedType1)) { - return 0; - } - return 1; - } else if (ElementUtils.isSubtype(boxedType2, boxedType1)) { - return -1; - } else { - return ElementUtils.getSimpleName(signature1).compareTo(ElementUtils.getSimpleName(signature2)); - } - } - - public String getName() { - if (method != null) { - return method.getSimpleName().toString(); - } else { - return getUniqueName(); - } - - } - - private static String formatType(TypeMirror type) { - return type == null ? "null" : ElementUtils.getSimpleName(type); - } - - @Override - public String toString() { - return String.format("%s %s(%s,%s)", formatType(getReturnType()), getName(), formatType(getFrameParameter()), getEvaluatedParameters()); - } - - public boolean sameParameters(ExecutableTypeData other) { - if (!typeEquals(other.getFrameParameter(), getFrameParameter())) { - return false; - } - - if (getEvaluatedCount() != other.getEvaluatedCount()) { - return false; - } - - for (int i = 0; i < getEvaluatedCount(); i++) { - if (!typeEquals(getEvaluatedParameters().get(i), other.getEvaluatedParameters().get(i))) { - return false; - } - } - return true; - } - - public boolean sameSignature(ExecutableTypeData other) { - if (!typeEquals(other.getReturnType(), getReturnType())) { - return false; - } - - if (other.getFrameParameter() != null) { - if (!typeEquals(getFrameParameter(), other.getFrameParameter())) { - return false; - } - } - - if (getEvaluatedCount() != other.getEvaluatedCount()) { - return false; - } - - for (int i = 0; i < getEvaluatedCount(); i++) { - if (!typeEquals(getEvaluatedParameters().get(i), other.getEvaluatedParameters().get(i))) { - return false; - } - } - - return true; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/GuardExpression.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/GuardExpression.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.expression.DSLExpression.Negate; -import com.oracle.truffle.dsl.processor.java.*; - -public final class GuardExpression extends MessageContainer { - - private final TemplateMethod source; - private final DSLExpression expression; - - public GuardExpression(TemplateMethod source, DSLExpression expression) { - this.source = source; - this.expression = expression; - } - - @Override - public Element getMessageElement() { - return source.getMessageElement(); - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return source.getMessageAnnotation(); - } - - @Override - public AnnotationValue getMessageAnnotationValue() { - return ElementUtils.getAnnotationValue(getMessageAnnotation(), "guards"); - } - - public DSLExpression getExpression() { - return expression; - } - - public boolean equalsNegated(GuardExpression other) { - boolean negated = false; - DSLExpression thisExpression = expression; - if (thisExpression instanceof Negate) { - negated = true; - thisExpression = ((Negate) thisExpression).getReceiver(); - } - - boolean otherNegated = false; - DSLExpression otherExpression = other.expression; - if (otherExpression instanceof Negate) { - otherNegated = true; - otherExpression = ((Negate) otherExpression).getReceiver(); - } - return Objects.equals(thisExpression, otherExpression) && negated != otherNegated; - } - - public boolean implies(GuardExpression other) { - if (Objects.equals(expression, other.expression)) { - return true; - } - return false; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ImplicitCastData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ImplicitCastData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.type.*; - -public class ImplicitCastData extends TemplateMethod { - - private final TypeMirror sourceType; - private final TypeMirror targetType; - - public ImplicitCastData(TemplateMethod method, TypeMirror sourceType, TypeMirror targetType) { - super(method); - this.sourceType = sourceType; - this.targetType = targetType; - } - - public TypeMirror getSourceType() { - return sourceType; - } - - public TypeMirror getTargetType() { - return targetType; - } - - @Override - public int compareTo(TemplateMethod o) { - return super.compareTo(o); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/MessageContainer.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/MessageContainer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; - -public abstract class MessageContainer implements Iterable { - - private final List messages = new ArrayList<>(); - - public final void addWarning(String text, Object... params) { - getMessages().add(new Message(null, null, this, String.format(text, params), Kind.WARNING)); - } - - public final void addWarning(AnnotationValue value, String text, Object... params) { - getMessages().add(new Message(null, value, this, String.format(text, params), Kind.WARNING)); - } - - public final void addError(String text, Object... params) { - addError(null, text, params); - } - - public final void addError(AnnotationValue value, String text, Object... params) { - getMessages().add(new Message(null, value, this, String.format(text, params), Kind.ERROR)); - } - - public final void addError(AnnotationMirror mirror, AnnotationValue value, String text, Object... params) { - getMessages().add(new Message(mirror, value, this, String.format(text, params), Kind.ERROR)); - } - - protected List findChildContainers() { - return Collections.emptyList(); - } - - public abstract Element getMessageElement(); - - public MessageContainer getBaseContainer() { - return null; - } - - public Iterator iterator() { - return findChildContainers().iterator(); - } - - public final void emitMessages(ProcessorContext context, Log log) { - emitMessagesImpl(context, log, new HashSet(), null); - } - - private void emitMessagesImpl(ProcessorContext context, Log log, Set visitedSinks, List verifiedMessages) { - List childMessages; - if (verifiedMessages == null) { - childMessages = collectMessagesWithElementChildren(new HashSet(), getMessageElement()); - } else { - childMessages = verifiedMessages; - } - verifyExpectedMessages(context, log, childMessages); - - for (int i = getMessages().size() - 1; i >= 0; i--) { - emitDefault(context, log, getMessages().get(i)); - } - - for (MessageContainer sink : findChildContainers()) { - if (visitedSinks.contains(sink)) { - continue; - } - - visitedSinks.add(sink); - if (sink.getMessageElement() == this.getMessageElement()) { - sink.emitMessagesImpl(context, log, visitedSinks, childMessages); - } else { - sink.emitMessagesImpl(context, log, visitedSinks, null); - } - } - } - - private List collectMessagesWithElementChildren(Set visitedSinks, Element e) { - if (visitedSinks.contains(this)) { - return Collections.emptyList(); - } - visitedSinks.add(this); - - List foundMessages = new ArrayList<>(); - if (getMessageElement() != null && ElementUtils.typeEquals(getMessageElement().asType(), e.asType())) { - foundMessages.addAll(getMessages()); - } - for (MessageContainer sink : findChildContainers()) { - foundMessages.addAll(sink.collectMessagesWithElementChildren(visitedSinks, e)); - } - return foundMessages; - } - - private void verifyExpectedMessages(ProcessorContext context, Log log, List msgs) { - TypeElement expectError = context.getTruffleTypes().getExpectError(); - if (expectError != null) { - Element element = getMessageElement(); - if (element != null) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), expectError.asType()); - if (mirror != null) { - List values = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); - if (values == null) { - values = Collections.emptyList(); - } - if (values.size() != msgs.size()) { - log.message(Kind.ERROR, element, mirror, ElementUtils.getAnnotationValue(mirror, "value"), String.format("Error count expected %s but was %s.", values.size(), msgs.size())); - } - } - } - } - } - - private void emitDefault(ProcessorContext context, Log log, Message message) { - Kind kind = message.getKind(); - - Element messageElement = getMessageElement(); - AnnotationMirror messageAnnotation = getMessageAnnotation(); - AnnotationValue messageValue = getMessageAnnotationValue(); - if (message.getAnnotationValue() != null) { - messageValue = message.getAnnotationValue(); - } - if (message.getAnnotationMirror() != null) { - messageAnnotation = message.getAnnotationMirror(); - } - - String text = message.getText(); - - TypeElement expectError = context.getTruffleTypes().getExpectError(); - if (expectError != null) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError.asType()); - if (mirror != null) { - List expectedTexts = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); - boolean found = false; - for (String expectedText : expectedTexts) { - if (expectedText.endsWith("%") && text.startsWith(expectedText.substring(0, expectedText.length() - 1))) { - found = true; - break; - } else if (text.equals(expectedText)) { - found = true; - break; - } - } - if (!found) { - log.message(kind, messageElement, mirror, ElementUtils.getAnnotationValue(mirror, "value"), "Message expected one of '%s' but was '%s'.", expectedTexts, text); - } else { - return; - } - - } - } - - log.message(kind, messageElement, messageAnnotation, messageValue, text); - } - - public AnnotationMirror getMessageAnnotation() { - return null; - } - - public AnnotationValue getMessageAnnotationValue() { - return null; - } - - public final boolean hasErrors() { - return hasErrorsImpl(new HashSet()); - } - - public final List collectMessages() { - List collectedMessages = new ArrayList<>(); - collectMessagesImpl(collectedMessages, new HashSet()); - return collectedMessages; - } - - private void collectMessagesImpl(List collectedMessages, Set visitedSinks) { - collectedMessages.addAll(getMessages()); - for (MessageContainer sink : findChildContainers()) { - if (visitedSinks.contains(sink)) { - return; - } - - visitedSinks.add(sink); - sink.collectMessagesImpl(collectedMessages, visitedSinks); - } - } - - private boolean hasErrorsImpl(Set visitedSinks) { - for (Message msg : getMessages()) { - if (msg.getKind() == Kind.ERROR) { - return true; - } - } - for (MessageContainer sink : findChildContainers()) { - if (visitedSinks.contains(sink)) { - return false; - } - - visitedSinks.add(sink); - - if (sink.hasErrorsImpl(visitedSinks)) { - return true; - } - } - return false; - } - - public List getMessages() { - return messages; - } - - public static final class Message { - - private final MessageContainer originalContainer; - private final AnnotationMirror annotationMirror; - private final AnnotationValue annotationValue; - private final String text; - private final Kind kind; - - public Message(AnnotationMirror annotationMirror, AnnotationValue annotationValue, MessageContainer originalContainer, String text, Kind kind) { - this.annotationMirror = annotationMirror; - this.annotationValue = annotationValue; - this.originalContainer = originalContainer; - this.text = text; - this.kind = kind; - } - - public AnnotationMirror getAnnotationMirror() { - return annotationMirror; - } - - public AnnotationValue getAnnotationValue() { - return annotationValue; - } - - public MessageContainer getOriginalContainer() { - return originalContainer; - } - - public String getText() { - return text; - } - - public Kind getKind() { - return kind; - } - - @Override - public String toString() { - return kind + ": " + text; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/MethodSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/MethodSpec.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; - -public class MethodSpec { - - private final ParameterSpec returnType; - private final List optional = new ArrayList<>(); - private final List required = new ArrayList<>(); - private final List annotations = new ArrayList<>(); - - private boolean ignoreAdditionalParameters; - private boolean ignoreAdditionalSpecifications; - private boolean variableRequiredParameters; - - private List typeDefinitions; - - public MethodSpec(ParameterSpec returnType) { - this.returnType = returnType; - } - - public void setVariableRequiredParameters(boolean variableRequiredParameters) { - this.variableRequiredParameters = variableRequiredParameters; - } - - public boolean isVariableRequiredParameters() { - return variableRequiredParameters; - } - - public void setIgnoreAdditionalParameters(boolean ignoreAdditionalParameter) { - this.ignoreAdditionalParameters = ignoreAdditionalParameter; - } - - public boolean isIgnoreAdditionalParameters() { - return ignoreAdditionalParameters; - } - - public void addOptional(ParameterSpec spec) { - optional.add(spec); - } - - public ParameterSpec addRequired(ParameterSpec spec) { - required.add(spec); - return spec; - } - - public List getAnnotations() { - return annotations; - } - - public ParameterSpec getReturnType() { - return returnType; - } - - public List getRequired() { - return required; - } - - public List getOptional() { - return optional; - } - - public List getAll() { - List specs = new ArrayList<>(); - specs.add(getReturnType()); - specs.addAll(getOptional()); - specs.addAll(getRequired()); - return specs; - } - - public void applyTypeDefinitions(String prefix) { - this.typeDefinitions = createTypeDefinitions(prefix); - } - - private List createTypeDefinitions(String prefix) { - List typeDefs = new ArrayList<>(); - - int defIndex = 0; - for (ParameterSpec spec : getAll()) { - Collection allowedTypes = spec.getAllowedTypes(); - Collection types = spec.getAllowedTypes(); - if (types != null && allowedTypes.size() > 1) { - TypeDef foundDef = null; - for (TypeDef def : typeDefs) { - if (allowedTypes.equals(def.getTypes())) { - foundDef = def; - break; - } - } - if (foundDef == null) { - foundDef = new TypeDef(types, prefix + defIndex); - typeDefs.add(foundDef); - defIndex++; - } - - spec.setTypeDefinition(foundDef); - } - } - - return typeDefs; - } - - public String toSignatureString(String methodName) { - StringBuilder b = new StringBuilder(); - b.append(" "); - b.append(createTypeSignature(returnType, true)); - - b.append(" "); - b.append(methodName); - b.append("("); - - String sep = ""; - - for (ParameterSpec optionalSpec : getOptional()) { - b.append(sep); - b.append("["); - b.append(createTypeSignature(optionalSpec, false)); - b.append("]"); - sep = ", "; - } - - for (int i = 0; i < getRequired().size(); i++) { - ParameterSpec requiredSpec = getRequired().get(i); - b.append(sep); - - if (isVariableRequiredParameters() && i == getRequired().size() - 1) { - b.append(("{")); - } - b.append(createTypeSignature(requiredSpec, false)); - if (isVariableRequiredParameters() && i == getRequired().size() - 1) { - b.append(("}")); - } - - sep = ", "; - } - - b.append(")"); - - if (typeDefinitions != null && !typeDefinitions.isEmpty()) { - b.append("\n\n"); - - String lineSep = ""; - for (TypeDef def : typeDefinitions) { - b.append(lineSep); - b.append(" <").append(def.getName()).append(">"); - b.append(" = {"); - String separator = ""; - for (TypeMirror type : def.getTypes()) { - b.append(separator).append(ElementUtils.getSimpleName(type)); - separator = ", "; - } - b.append("}"); - lineSep = "\n"; - - } - } - return b.toString(); - } - - private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) { - StringBuilder builder = new StringBuilder(); - TypeDef foundTypeDef = spec.getTypeDefinition(); - if (foundTypeDef != null) { - builder.append("<" + foundTypeDef.getName() + ">"); - } else if (spec.getAllowedTypes().size() >= 1) { - builder.append(ElementUtils.getSimpleName(spec.getAllowedTypes().iterator().next())); - } else { - builder.append("void"); - } - if (!typeOnly) { - builder.append(" "); - builder.append(spec.getName()); - } - return builder.toString(); - } - - @Override - public String toString() { - return toSignatureString("methodName"); - } - - static final class TypeDef { - - private final Collection types; - private final String name; - - private TypeDef(Collection types, String name) { - this.types = types; - this.name = name; - } - - public Collection getTypes() { - return types; - } - - public String getName() { - return name; - } - } - - public void setIgnoreAdditionalSpecifications(boolean ignoreAdditoinalSpecifications) { - this.ignoreAdditionalSpecifications = ignoreAdditoinalSpecifications; - } - - public boolean isIgnoreAdditionalSpecifications() { - return ignoreAdditionalSpecifications; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; - -public class NodeChildData extends MessageContainer { - - public enum Cardinality { - ONE, - MANY; - - public boolean isMany() { - return this == MANY; - } - - public boolean isOne() { - return this == ONE; - } - } - - private final Element sourceElement; - private final AnnotationMirror sourceAnnotationMirror; - private final String name; - private final TypeMirror type; - private final TypeMirror originalType; - private final Element accessElement; - private final Cardinality cardinality; - - private List executeWith = Collections.emptyList(); - - private NodeData childNode; - - public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality) { - this.sourceElement = sourceElement; - this.sourceAnnotationMirror = sourceMirror; - this.name = name; - this.type = nodeType; - this.originalType = originalNodeType; - this.accessElement = accessElement; - this.cardinality = cardinality; - } - - public List getExecuteWith() { - return executeWith; - } - - public void setExecuteWith(List executeWith) { - this.executeWith = executeWith; - } - - public ExecutableTypeData findExecutableType(TypeMirror targetType) { - return childNode.findExecutableType(targetType, getExecuteWith().size()); - } - - public List findGenericExecutableTypes(ProcessorContext context) { - return childNode.findGenericExecutableTypes(context, getExecuteWith().size()); - } - - public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) { - return childNode.findAnyGenericExecutableType(context, getExecuteWith().size()); - } - - public TypeMirror getOriginalType() { - return originalType; - } - - @Override - public Element getMessageElement() { - return sourceElement; - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return sourceAnnotationMirror; - } - - public void setNode(NodeData nodeData) { - this.childNode = nodeData; - if (nodeData != null) { - getMessages().addAll(nodeData.collectMessages()); - } - } - - public Element getAccessElement() { - return accessElement; - } - - public TypeMirror getNodeType() { - return type; - } - - public Cardinality getCardinality() { - return cardinality; - } - - public NodeData getNodeData() { - return childNode; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", node=" + getNodeData() + "]"; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,599 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; - -public class NodeData extends Template implements Comparable { - - private final String nodeId; - private final String shortName; - private final List enclosingNodes = new ArrayList<>(); - private NodeData declaringNode; - - private final TypeSystemData typeSystem; - private final List children; - private final List childExecutions; - private final List fields; - - private ParameterSpec instanceParameterSpec; - - private final List specializations = new ArrayList<>(); - private final List shortCircuits = new ArrayList<>(); - private final List casts = new ArrayList<>(); - private final List executableTypes = new ArrayList<>(); - - private final NodeExecutionData thisExecution; - private final boolean generateFactory; - - private TypeMirror frameType; - - public NodeData(ProcessorContext context, TypeElement type, String shortName, TypeSystemData typeSystem, boolean generateFactory) { - super(context, type, null); - this.nodeId = ElementUtils.getSimpleName(type); - this.shortName = shortName; - this.typeSystem = typeSystem; - this.fields = new ArrayList<>(); - this.children = new ArrayList<>(); - this.childExecutions = new ArrayList<>(); - this.thisExecution = new NodeExecutionData(new NodeChildData(null, null, "this", getNodeType(), getNodeType(), null, Cardinality.ONE), -1, -1, false); - this.thisExecution.getChild().setNode(this); - this.generateFactory = generateFactory; - } - - public NodeData(ProcessorContext context, TypeElement type) { - this(context, type, null, null, false); - } - - public boolean isGenerateFactory() { - return generateFactory; - } - - public NodeExecutionData getThisExecution() { - return thisExecution; - } - - public boolean isFallbackReachable() { - SpecializationData generic = getGenericSpecialization(); - if (generic != null) { - return generic.isReachable(); - } - return false; - } - - public void setFrameType(TypeMirror frameType) { - this.frameType = frameType; - } - - public TypeMirror getFrameType() { - return frameType; - } - - public void addEnclosedNode(NodeData node) { - this.enclosingNodes.add(node); - node.declaringNode = this; - } - - public List getChildExecutions() { - return childExecutions; - } - - public Set findSpecializedTypes(NodeExecutionData execution) { - Set types = new HashSet<>(); - for (SpecializationData specialization : getSpecializations()) { - if (!specialization.isSpecialized()) { - continue; - } - List parameters = specialization.findByExecutionData(execution); - for (Parameter parameter : parameters) { - TypeMirror type = parameter.getType(); - if (type == null) { - throw new AssertionError(); - } - types.add(type); - } - } - return types; - } - - public Collection findSpecializedReturnTypes() { - Set types = new HashSet<>(); - for (SpecializationData specialization : getSpecializations()) { - if (!specialization.isSpecialized()) { - continue; - } - types.add(specialization.getReturnType().getType()); - } - return types; - } - - public int getExecutionCount() { - return getChildExecutions().size(); - } - - public int getSignatureSize() { - int count = 0; - for (NodeExecutionData execution : getChildExecutions()) { - if (execution.isShortCircuit()) { - count++; - } - count++; - } - return count; - } - - public boolean isFrameUsedByAnyGuard() { - for (SpecializationData specialization : specializations) { - if (!specialization.isReachable()) { - continue; - } - Parameter frame = specialization.getFrame(); - if (frame != null) { - for (GuardExpression guard : specialization.getGuards()) { - if (guard.getExpression().findBoundVariableElements().contains(frame.getVariableElement())) { - return true; - } - } - for (CacheExpression cache : specialization.getCaches()) { - if (cache.getExpression().findBoundVariableElements().contains(frame.getVariableElement())) { - return true; - } - } - } - } - return false; - } - - public List getCasts() { - return casts; - } - - public String getShortName() { - return shortName; - } - - public List getFields() { - return fields; - } - - @Override - protected List findChildContainers() { - List containerChildren = new ArrayList<>(); - if (enclosingNodes != null) { - containerChildren.addAll(enclosingNodes); - } - if (typeSystem != null) { - containerChildren.add(typeSystem); - } - if (specializations != null) { - for (MessageContainer specialization : specializations) { - if (specialization.getMessageElement() != null) { - containerChildren.add(specialization); - } - } - } - if (executableTypes != null) { - containerChildren.addAll(getExecutableTypes()); - } - if (shortCircuits != null) { - containerChildren.addAll(shortCircuits); - } - if (children != null) { - containerChildren.addAll(children); - } - if (fields != null) { - containerChildren.addAll(fields); - } - if (casts != null) { - containerChildren.addAll(casts); - } - return containerChildren; - } - - public ParameterSpec getInstanceParameterSpec() { - return instanceParameterSpec; - } - - public void setInstanceParameterSpec(ParameterSpec instanceParameter) { - this.instanceParameterSpec = instanceParameter; - } - - public String getNodeId() { - return nodeId; - } - - public TypeMirror getNodeType() { - return getTemplateType().asType(); - } - - public boolean needsFactory() { - if (specializations == null) { - return false; - } - if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) { - return false; - } - - boolean noSpecialization = true; - for (SpecializationData specialization : specializations) { - noSpecialization = noSpecialization && !specialization.isSpecialized(); - } - return !noSpecialization; - } - - public boolean supportsFrame() { - if (executableTypes != null) { - for (ExecutableTypeData execType : getExecutableTypes(-1)) { - if (execType.getFrameParameter() == null) { - return false; - } - } - } - return true; - } - - public NodeExecutionData findExecutionByExpression(String childNameExpression) { - String childName = childNameExpression; - int index = -1; - - int start = childName.indexOf('['); - int end = childName.lastIndexOf(']'); - if (start != -1 && end != -1 && start < end) { - try { - index = Integer.parseInt(childName.substring(start + 1, end)); - childName = childName.substring(0, start); - childName = NodeExecutionData.createName(childName, index); - } catch (NumberFormatException e) { - // ignore - } - } - - for (NodeExecutionData execution : childExecutions) { - if (execution.getName().equals(childName) && (execution.getChildIndex() == -1 || execution.getChildIndex() == index)) { - return execution; - } - } - return null; - } - - public List getNodesWithFactories() { - List nodeChildren = new ArrayList<>(); - for (NodeData child : getEnclosingNodes()) { - if (child.needsFactory() && child.isGenerateFactory()) { - nodeChildren.add(child); - } - nodeChildren.addAll(child.getNodesWithFactories()); - } - return nodeChildren; - } - - public NodeData getDeclaringNode() { - return declaringNode; - } - - public List getEnclosingNodes() { - return enclosingNodes; - } - - public List getAllTemplateMethods() { - List methods = new ArrayList<>(); - - for (SpecializationData specialization : getSpecializations()) { - methods.add(specialization.getMethod()); - } - - for (ExecutableTypeData execType : getExecutableTypes()) { - if (execType.getMethod() != null) { - methods.add(execType.getMethod()); - } - } - for (ShortCircuitData shortcircuit : getShortCircuits()) { - methods.add(shortcircuit.getMethod()); - } - - if (getCasts() != null) { - for (CreateCastData castData : getCasts()) { - methods.add(castData.getMethod()); - } - } - - return methods; - } - - public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) { - List types = findGenericExecutableTypes(context, evaluatedCount); - for (ExecutableTypeData type : types) { - if (context.isType(type.getReturnType(), Object.class)) { - return type; - } - } - - for (ExecutableTypeData type : types) { - if (!context.isType(type.getReturnType(), void.class)) { - return type; - } - } - - for (ExecutableTypeData type : types) { - return type; - } - return null; - } - - public List getExecutableTypes(int evaluatedCount) { - if (evaluatedCount == -1) { - return executableTypes; - } else { - List filteredTypes = new ArrayList<>(); - for (ExecutableTypeData type : executableTypes) { - if (type.getEvaluatedCount() == evaluatedCount) { - filteredTypes.add(type); - } - } - return filteredTypes; - } - } - - public List findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) { - List types = new ArrayList<>(); - for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) { - if (!type.hasUnexpectedValue(context)) { - types.add(type); - } - } - return types; - } - - public ExecutableTypeData findExecutableType(TypeMirror primitiveType, int evaluatedCount) { - for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) { - if (ElementUtils.typeEquals(type.getReturnType(), primitiveType)) { - return type; - } - } - return null; - } - - public boolean needsRewrites(ProcessorContext context) { - boolean needsRewrites = false; - - for (SpecializationData specialization : getSpecializations()) { - if (specialization.hasRewrite(context)) { - needsRewrites = true; - break; - } - } - return needsRewrites || getSpecializations().size() > 1; - } - - public SpecializationData getPolymorphicSpecialization() { - for (SpecializationData specialization : specializations) { - if (specialization.isPolymorphic()) { - return specialization; - } - } - return null; - } - - public SpecializationData getGenericSpecialization() { - for (SpecializationData specialization : specializations) { - if (specialization.isFallback()) { - return specialization; - } - } - return null; - } - - public SpecializationData getUninitializedSpecialization() { - for (SpecializationData specialization : specializations) { - if (specialization.isUninitialized()) { - return specialization; - } - } - return null; - } - - @Override - public TypeSystemData getTypeSystem() { - return typeSystem; - } - - @Override - public String dump() { - return dump(0); - } - - private String dump(int level) { - String indent = ""; - for (int i = 0; i < level; i++) { - indent += " "; - } - StringBuilder builder = new StringBuilder(); - - builder.append(String.format("%s%s {", indent, toString())); - - dumpProperty(builder, indent, "templateClass", ElementUtils.getQualifiedName(getTemplateType())); - dumpProperty(builder, indent, "typeSystem", getTypeSystem()); - dumpProperty(builder, indent, "fields", getChildren()); - dumpProperty(builder, indent, "executableTypes", getExecutableTypes()); - dumpProperty(builder, indent, "specializations", getSpecializations()); - dumpProperty(builder, indent, "casts", getCasts()); - dumpProperty(builder, indent, "messages", collectMessages()); - if (getEnclosingNodes().size() > 0) { - builder.append(String.format("\n%s children = [", indent)); - for (NodeData node : getEnclosingNodes()) { - builder.append("\n"); - builder.append(node.dump(level + 1)); - } - builder.append(String.format("\n%s ]", indent)); - } - builder.append(String.format("%s}", indent)); - return builder.toString(); - } - - private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) { - if (value instanceof List) { - List list = (List) value; - if (!list.isEmpty()) { - b.append(String.format("\n%s %s = %s", indent, propertyName, dumpList(indent, (List) value))); - } - } else { - if (value != null) { - b.append(String.format("\n%s %s = %s", indent, propertyName, value)); - } - } - } - - private static String dumpList(String indent, List array) { - if (array == null) { - return "null"; - } - - if (array.isEmpty()) { - return "[]"; - } else if (array.size() == 1) { - return "[" + array.get(0).toString() + "]"; - } - - StringBuilder b = new StringBuilder(); - b.append("["); - for (Object object : array) { - b.append("\n "); - b.append(indent); - b.append(object); - b.append(", "); - } - b.append("\n ").append(indent).append("]"); - return b.toString(); - } - - public NodeChildData findChild(String name) { - for (NodeChildData field : getChildren()) { - if (field.getName().equals(name)) { - return field; - } - } - return null; - } - - public List getChildren() { - return children; - } - - public List getSpecializations() { - return specializations; - } - - public ExecutableTypeData getGenericExecutableType(ExecutableTypeData typeHint) { - ExecutableTypeData polymorphicDelegate = null; - if (typeHint != null) { - polymorphicDelegate = typeHint; - while (polymorphicDelegate.getDelegatedTo() != null && polymorphicDelegate.getEvaluatedCount() != getSignatureSize()) { - polymorphicDelegate = polymorphicDelegate.getDelegatedTo(); - } - } - if (polymorphicDelegate == null) { - for (ExecutableTypeData type : getExecutableTypes()) { - if (type.getDelegatedTo() == null && type.getEvaluatedCount() == getSignatureSize()) { - polymorphicDelegate = type; - break; - } - } - } - return polymorphicDelegate; - } - - public List getExecutableTypes() { - return getExecutableTypes(-1); - } - - public List getShortCircuits() { - return shortCircuits; - } - - public int getMinimalEvaluatedParameters() { - int minimalEvaluatedParameters = Integer.MAX_VALUE; - for (ExecutableTypeData type : getExecutableTypes()) { - minimalEvaluatedParameters = Math.min(minimalEvaluatedParameters, type.getEvaluatedCount()); - } - return minimalEvaluatedParameters; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + getNodeId() + "]"; - } - - public CreateCastData findCast(String name) { - if (getCasts() != null) { - for (CreateCastData cast : getCasts()) { - if (cast.getChildNames().contains(name)) { - return cast; - } - } - } - return null; - } - - public int compareTo(NodeData o) { - return getNodeId().compareTo(o.getNodeId()); - } - - public TypeMirror getGenericType(NodeExecutionData execution) { - return ElementUtils.getCommonSuperType(getContext(), getGenericTypes(execution)); - } - - public List getGenericTypes(NodeExecutionData execution) { - List types = new ArrayList<>(); - - // add types possible through return types and evaluated parameters in execute methods - if (execution.getChild() != null) { - for (ExecutableTypeData executable : execution.getChild().getNodeData().getExecutableTypes()) { - if (executable.hasUnexpectedValue(getContext())) { - continue; - } - types.add(executable.getReturnType()); - } - } - - int executionIndex = execution.getIndex(); - if (executionIndex >= 0) { - for (ExecutableTypeData typeData : getExecutableTypes()) { - List signatureParameters = typeData.getSignatureParameters(); - if (executionIndex < signatureParameters.size()) { - TypeMirror genericType = signatureParameters.get(executionIndex); - types.add(genericType); - } - } - } - - return ElementUtils.uniqueSortedTypes(types, false); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; - -public class NodeExecutionData { - - private final NodeChildData child; - private final String name; - private final int index; - private final int childIndex; - private final boolean shortCircuit; - private final List typeRestrictions = new ArrayList<>(); - - public NodeExecutionData(NodeChildData child, int index, int childIndex, boolean shortCircuit) { - this.child = child; - this.index = index; - this.childIndex = childIndex; - this.shortCircuit = shortCircuit; - this.name = createName(); - } - - private String createName() { - return child != null ? createName(child.getName(), childIndex) : ("arg" + index); - } - - public int getIndex() { - return index; - } - - public List getTypeRestrictions() { - return typeRestrictions; - } - - public TypeMirror getNodeType() { - TypeMirror type; - if (child.getCardinality() == Cardinality.MANY && child.getNodeType().getKind() == TypeKind.ARRAY) { - type = ((ArrayType) child.getNodeType()).getComponentType(); - } else { - type = child.getNodeType(); - } - return type; - } - - public String getName() { - return name; - } - - public NodeChildData getChild() { - return child; - } - - public int getChildIndex() { - return childIndex; - } - - public boolean isIndexed() { - return childIndex > -1; - } - - public boolean isShortCircuit() { - return shortCircuit; - } - - public String getIndexedName() { - return createIndexedName(child, childIndex); - } - - public static String createIndexedName(NodeChildData child, int varArgsIndex) { - String shortCircuitName = child.getName(); - if (child.getCardinality().isMany()) { - shortCircuitName = shortCircuitName + "[" + varArgsIndex + "]"; - } - return shortCircuitName; - } - - public static String createName(String childName, int index) { - if (index > -1) { - return childName + index; - } - return childName; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeFieldData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeFieldData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +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.dsl.processor.model; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public class NodeFieldData extends MessageContainer { - - private final Element messageElement; - private final AnnotationMirror messageAnnotation; - private final boolean generated; - private ExecutableElement getter; - private final VariableElement variable; - - public NodeFieldData(Element messageElement, AnnotationMirror messageAnnotation, VariableElement variableElement, boolean generated) { - this.messageElement = messageElement; - this.messageAnnotation = messageAnnotation; - this.generated = generated; - this.variable = variableElement; - } - - public VariableElement getVariable() { - return variable; - } - - public void setGetter(ExecutableElement getter) { - this.getter = getter; - } - - @Override - public Element getMessageElement() { - return messageElement; - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return messageAnnotation; - } - - public String getName() { - return variable.getSimpleName().toString(); - } - - public TypeMirror getType() { - return variable.asType(); - } - - public boolean isGenerated() { - return generated; - } - - public ExecutableElement getGetter() { - return getter; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/Parameter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/Parameter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +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.dsl.processor.model; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public final class Parameter { - - private final ParameterSpec specification; - private TemplateMethod method; - private String localName; - private final int specificationVarArgsIndex; - private final int typeVarArgsIndex; - private final VariableElement variableElement; - private final TypeMirror type; - - public Parameter(ParameterSpec specification, VariableElement variableElement, int specificationVarArgsIndex, int typeVarArgsIndex) { - this.specification = specification; - this.variableElement = variableElement; - this.type = variableElement.asType(); - this.specificationVarArgsIndex = specificationVarArgsIndex; - - String valueName = specification.getName() + "Value"; - if (specificationVarArgsIndex > -1) { - valueName += specificationVarArgsIndex; - } - this.typeVarArgsIndex = typeVarArgsIndex; - this.localName = valueName; - } - - public Parameter(Parameter parameter) { - this.specification = parameter.specification; - this.specificationVarArgsIndex = parameter.specificationVarArgsIndex; - this.localName = parameter.localName; - this.typeVarArgsIndex = parameter.typeVarArgsIndex; - this.variableElement = parameter.variableElement; - this.type = parameter.type; - } - - public Parameter(Parameter parameter, TypeMirror newType) { - this.specification = parameter.specification; - this.specificationVarArgsIndex = parameter.specificationVarArgsIndex; - this.localName = parameter.localName; - this.typeVarArgsIndex = parameter.typeVarArgsIndex; - this.variableElement = parameter.variableElement; - this.type = newType; - } - - public void setLocalName(String localName) { - this.localName = localName; - } - - public VariableElement getVariableElement() { - return variableElement; - } - - public int getTypeVarArgsIndex() { - return typeVarArgsIndex; - } - - public int getSpecificationVarArgsIndex() { - return specificationVarArgsIndex; - } - - public String getLocalName() { - return localName; - } - - void setMethod(TemplateMethod method) { - this.method = method; - } - - public ParameterSpec getSpecification() { - return specification; - } - - public TemplateMethod getMethod() { - return method; - } - - public TypeMirror getType() { - return type; - } - - public boolean isTypeVarArgs() { - return typeVarArgsIndex >= 0; - } - - public Parameter getPreviousParameter() { - return method.getPreviousParam(this); - } - - @Override - public String toString() { - return "Parameter [localName=" + localName + ", type=" + getType() + ", variableElement=" + variableElement + "]"; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ParameterSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ParameterSpec.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.MethodSpec.TypeDef; - -public class ParameterSpec { - - private final String name; - private final Collection allowedTypes; - private final boolean anyType; - - /** Type is bound to local final variable. */ - private boolean local; - private boolean signature; - private boolean allowSubclasses = true; - - /** Optional bound execution of node. */ - private NodeExecutionData execution; - private TypeDef typeDefinition; - - public ParameterSpec(String name, Collection allowedTypes) { - this.name = name; - this.allowedTypes = allowedTypes; - boolean anyTypeTemp = false; - for (TypeMirror type : allowedTypes) { - if (ElementUtils.isObject(type)) { - anyTypeTemp = true; - break; - } - } - this.anyType = anyTypeTemp; - } - - public boolean isAnnotated() { - return false; - } - - public ParameterSpec(ParameterSpec original, TypeMirror newType) { - this(original.name, newType); - this.local = original.local; - this.signature = original.signature; - this.execution = original.execution; - this.typeDefinition = original.typeDefinition; - this.allowSubclasses = original.allowSubclasses; - } - - public ParameterSpec(String name, TypeMirror type) { - this(name, Arrays.asList(type)); - } - - public void setAllowSubclasses(boolean allowSubclasses) { - this.allowSubclasses = allowSubclasses; - } - - public NodeExecutionData getExecution() { - return execution; - } - - public void setExecution(NodeExecutionData executionData) { - this.execution = executionData; - this.signature = execution != null; - } - - public void setSignature(boolean signature) { - this.signature = signature; - } - - void setTypeDefinition(TypeDef typeDefinition) { - this.typeDefinition = typeDefinition; - } - - TypeDef getTypeDefinition() { - return typeDefinition; - } - - public void setLocal(boolean local) { - this.local = local; - } - - public boolean isSignature() { - return signature; - } - - public boolean isLocal() { - return local; - } - - public String getName() { - return name; - } - - public Collection getAllowedTypes() { - return allowedTypes; - } - - public boolean matches(VariableElement variable) { - if (anyType) { - return true; - } else { - for (TypeMirror type : allowedTypes) { - if (ElementUtils.typeEquals(variable.asType(), type)) { - return true; - } - } - if (allowSubclasses) { - for (TypeMirror type : allowedTypes) { - if (ElementUtils.isSubtypeBoxed(ProcessorContext.getInstance(), variable.asType(), type)) { - return true; - } - } - } - } - return false; - } - - @Override - public String toString() { - return toSignatureString(false); - } - - public String toSignatureString(boolean typeOnly) { - StringBuilder builder = new StringBuilder(); - if (typeDefinition != null) { - builder.append("<" + typeDefinition.getName() + ">"); - } else if (getAllowedTypes().size() >= 1) { - builder.append(ElementUtils.getSimpleName(getAllowedTypes().iterator().next())); - } else { - builder.append("void"); - } - if (!typeOnly) { - builder.append(" "); - builder.append(getName()); - } - return builder.toString(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ShortCircuitData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ShortCircuitData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import com.oracle.truffle.dsl.processor.java.*; - -public class ShortCircuitData extends TemplateMethod { - - private ShortCircuitData genericShortCircuitMethod; - private final String valueName; - - public ShortCircuitData(TemplateMethod template, String valueName) { - super(template); - this.valueName = valueName; - } - - public String getValueName() { - return valueName; - } - - public void setGenericShortCircuitMethod(ShortCircuitData genericShortCircuitMethod) { - this.genericShortCircuitMethod = genericShortCircuitMethod; - } - - public boolean isGeneric() { - return genericShortCircuitMethod == null; - } - - public ShortCircuitData getGeneric() { - if (isGeneric()) { - return this; - } else { - return genericShortCircuitMethod; - } - } - - public boolean isCompatibleTo(SpecializationData specialization) { - if (isGeneric() && specialization.isFallback()) { - return true; - } - - for (Parameter param : getParameters()) { - Parameter specializationParam = specialization.findParameter(param.getLocalName()); - if (!ElementUtils.typeEquals(param.getType(), specializationParam.getType())) { - return false; - } - } - return true; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,395 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.java.*; - -public final class SpecializationData extends TemplateMethod { - - public enum SpecializationKind { - UNINITIALIZED, - SPECIALIZED, - POLYMORPHIC, - FALLBACK - } - - private final NodeData node; - private SpecializationKind kind; - private final List exceptions; - private List guards = Collections.emptyList(); - private List caches = Collections.emptyList(); - private List assumptionExpressions = Collections.emptyList(); - private List shortCircuits; - private final Set contains = new TreeSet<>(); - private final Set containsNames = new TreeSet<>(); - private final Set excludedBy = new TreeSet<>(); - private String insertBeforeName; - private SpecializationData insertBefore; - private boolean reachable; - private int index; - private DSLExpression limitExpression; - - public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, List exceptions) { - super(template); - this.node = node; - this.kind = kind; - this.exceptions = exceptions; - this.index = template.getNaturalOrder(); - - for (SpecializationThrowsData exception : exceptions) { - exception.setSpecialization(this); - } - } - - public boolean isCacheBoundByGuard(CacheExpression cacheExpression) { - for (GuardExpression expression : getGuards()) { - if (expression.getExpression().findBoundVariableElements().contains(cacheExpression.getParameter().getVariableElement())) { - return true; - } - } - - // check all next binding caches if they are bound by guard - Set boundVariables = cacheExpression.getExpression().findBoundVariableElements(); - boolean found = false; - for (CacheExpression expression : getCaches()) { - if (cacheExpression == expression) { - found = true; - } else if (found) { - if (boundVariables.contains(expression.getParameter().getVariableElement())) { - if (isCacheBoundByGuard(expression)) { - return true; - } - } - } - } - return false; - } - - public void setKind(SpecializationKind kind) { - this.kind = kind; - } - - public boolean isDynamicParameterBound(DSLExpression expression) { - Set boundVariables = expression.findBoundVariableElements(); - for (Parameter parameter : getDynamicParameters()) { - if (boundVariables.contains(parameter.getVariableElement())) { - return true; - } - } - return false; - } - - public Parameter findByVariable(VariableElement variable) { - for (Parameter parameter : getParameters()) { - if (ElementUtils.variableEquals(parameter.getVariableElement(), variable)) { - return parameter; - } - } - return null; - } - - public DSLExpression getLimitExpression() { - return limitExpression; - } - - public void setLimitExpression(DSLExpression limitExpression) { - this.limitExpression = limitExpression; - } - - public void setInsertBefore(SpecializationData insertBefore) { - this.insertBefore = insertBefore; - } - - public void setInsertBeforeName(String insertBeforeName) { - this.insertBeforeName = insertBeforeName; - } - - public SpecializationData getInsertBefore() { - return insertBefore; - } - - public String getInsertBeforeName() { - return insertBeforeName; - } - - public Set getContainsNames() { - return containsNames; - } - - public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) { - this(node, template, kind, new ArrayList()); - } - - public Set getContains() { - return contains; - } - - public Set getExcludedBy() { - return excludedBy; - } - - public void setReachable(boolean reachable) { - this.reachable = reachable; - } - - public boolean isReachable() { - return reachable; - } - - public boolean isPolymorphic() { - return kind == SpecializationKind.POLYMORPHIC; - } - - @Override - protected List findChildContainers() { - List sinks = new ArrayList<>(); - if (exceptions != null) { - sinks.addAll(exceptions); - } - if (guards != null) { - sinks.addAll(guards); - } - if (caches != null) { - sinks.addAll(caches); - } - if (assumptionExpressions != null) { - sinks.addAll(assumptionExpressions); - } - return sinks; - } - - public boolean hasRewrite(ProcessorContext context) { - if (!getExceptions().isEmpty()) { - return true; - } - if (!getGuards().isEmpty()) { - return true; - } - if (!getAssumptionExpressions().isEmpty()) { - return true; - } - - for (Parameter parameter : getSignatureParameters()) { - NodeChildData child = parameter.getSpecification().getExecution().getChild(); - if (child != null) { - ExecutableTypeData type = child.findExecutableType(parameter.getType()); - if (type == null) { - type = child.findAnyGenericExecutableType(context); - } - if (type.hasUnexpectedValue(context)) { - return true; - } - if (ElementUtils.needsCastTo(type.getReturnType(), parameter.getType())) { - return true; - } - } - } - return false; - } - - @Override - public int compareTo(TemplateMethod other) { - if (this == other) { - return 0; - } else if (!(other instanceof SpecializationData)) { - return super.compareTo(other); - } - SpecializationData m2 = (SpecializationData) other; - int kindOrder = kind.compareTo(m2.kind); - if (kindOrder != 0) { - return kindOrder; - } - - int compare = 0; - int order1 = index; - int order2 = m2.index; - if (order1 != NO_NATURAL_ORDER && order2 != NO_NATURAL_ORDER) { - compare = Integer.compare(order1, order2); - if (compare != 0) { - return compare; - } - } - - return super.compareTo(other); - } - - public void setIndex(int order) { - this.index = order; - } - - public int getIndex() { - return index; - } - - public NodeData getNode() { - return node; - } - - public void setGuards(List guards) { - this.guards = guards; - } - - public boolean isSpecialized() { - return kind == SpecializationKind.SPECIALIZED; - } - - public boolean isFallback() { - return kind == SpecializationKind.FALLBACK; - } - - public boolean isUninitialized() { - return kind == SpecializationKind.UNINITIALIZED; - } - - public List getExceptions() { - return exceptions; - } - - public List getGuards() { - return guards; - } - - public void setShortCircuits(List shortCircuits) { - this.shortCircuits = shortCircuits; - } - - public List getShortCircuits() { - return shortCircuits; - } - - public SpecializationData findNextSpecialization() { - List specializations = node.getSpecializations(); - for (int i = 0; i < specializations.size() - 1; i++) { - if (specializations.get(i) == this) { - return specializations.get(i + 1); - } - } - return null; - } - - @Override - public String toString() { - return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getDynamicTypes()); - } - - public boolean isFrameUsed() { - return getFrame() != null; - } - - public List getCaches() { - return caches; - } - - public void setCaches(List caches) { - this.caches = caches; - } - - public void setAssumptionExpressions(List assumptionExpressions) { - this.assumptionExpressions = assumptionExpressions; - } - - public List getAssumptionExpressions() { - return assumptionExpressions; - } - - public boolean hasMultipleInstances() { - if (!getCaches().isEmpty()) { - for (GuardExpression guard : getGuards()) { - DSLExpression guardExpression = guard.getExpression(); - Set boundVariables = guardExpression.findBoundVariableElements(); - if (isDynamicParameterBound(guardExpression)) { - for (CacheExpression cache : getCaches()) { - if (boundVariables.contains(cache.getParameter().getVariableElement())) { - return true; - } - } - } - } - } - return false; - } - - public boolean isReachableAfter(SpecializationData prev) { - if (!prev.isSpecialized()) { - return true; - } - - if (!prev.getExceptions().isEmpty()) { - // may get excluded by exception - return true; - } - - if (hasMultipleInstances()) { - // may fallthrough due to limit - return true; - } - - Iterator currentSignature = getSignatureParameters().iterator(); - Iterator prevSignature = prev.getSignatureParameters().iterator(); - - TypeSystemData typeSystem = prev.getNode().getTypeSystem(); - while (currentSignature.hasNext() && prevSignature.hasNext()) { - TypeMirror currentType = currentSignature.next().getType(); - TypeMirror prevType = prevSignature.next().getType(); - - if (!typeSystem.isImplicitSubtypeOf(currentType, prevType)) { - return true; - } - } - - if (!prev.getAssumptionExpressions().isEmpty()) { - // TODO: chumer: we could at least check reachability after trivial assumptions - // not sure if this is worth it. - return true; - } - - Iterator prevGuards = prev.getGuards().iterator(); - Iterator currentGuards = getGuards().iterator(); - while (prevGuards.hasNext()) { - GuardExpression prevGuard = prevGuards.next(); - GuardExpression currentGuard = currentGuards.hasNext() ? currentGuards.next() : null; - if (currentGuard == null || !currentGuard.implies(prevGuard)) { - return true; - } - } - - return false; - } - - public CacheExpression findCache(Parameter resolvedParameter) { - for (CacheExpression cache : getCaches()) { - if (cache.getParameter() == resolvedParameter) { - return cache; - } - } - return null; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationThrowsData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationThrowsData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -public class SpecializationThrowsData extends MessageContainer { - - private final AnnotationValue annotationValue; - private final AnnotationMirror annotationMirror; - private final TypeMirror javaClass; - private SpecializationData specialization; - - public SpecializationThrowsData(AnnotationMirror annotationMirror, AnnotationValue value, TypeMirror javaClass) { - this.annotationMirror = annotationMirror; - this.annotationValue = value; - this.javaClass = javaClass; - } - - void setSpecialization(SpecializationData specialization) { - this.specialization = specialization; - } - - @Override - public Element getMessageElement() { - return specialization.getMessageElement(); - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return annotationMirror; - } - - @Override - public AnnotationValue getMessageAnnotationValue() { - return annotationValue; - } - - public TypeMirror getJavaClass() { - return javaClass; - } - - public SpecializationData getSpecialization() { - return specialization; - } - - public AnnotationMirror getAnnotationMirror() { - return annotationMirror; - } - - public SpecializationData getTransitionTo() { - return specialization.findNextSpecialization(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/Template.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/Template.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; - -public abstract class Template extends MessageContainer { - - private final ProcessorContext context; - private final TypeElement templateType; - private final AnnotationMirror annotation; - - public Template(ProcessorContext context, TypeElement templateType, AnnotationMirror annotation) { - this.context = context; - this.templateType = templateType; - this.annotation = annotation; - } - - public ProcessorContext getContext() { - return context; - } - - @Override - public MessageContainer getBaseContainer() { - return this; - } - - public abstract TypeSystemData getTypeSystem(); - - @Override - public Element getMessageElement() { - return templateType; - } - - public String dump() { - return toString(); - } - - @Override - protected List findChildContainers() { - return Collections.emptyList(); - } - - public TypeElement getTemplateType() { - return templateType; - } - - public AnnotationMirror getTemplateTypeAnnotation() { - return annotation; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + ElementUtils.getSimpleName(getTemplateType()) + "]"; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TemplateMethod.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TemplateMethod.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +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.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.util.*; - -/** - * Note: this class has a natural ordering that is inconsistent with equals. - */ -public class TemplateMethod extends MessageContainer implements Comparable { - - public static final String FRAME_NAME = "frameValue"; - public static final int NO_NATURAL_ORDER = -1; - - private String id; - private final Template template; - private final int naturalOrder; - private final MethodSpec specification; - private final ExecutableElement method; - private final AnnotationMirror markerAnnotation; - private Parameter returnType; - private final List parameters; - private final Map parameterCache = new HashMap<>(); - - public TemplateMethod(String id, int naturalOrder, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, Parameter returnType, - List parameters) { - this.template = template; - this.specification = specification; - this.naturalOrder = naturalOrder; - this.method = method; - this.markerAnnotation = markerAnnotation; - this.returnType = returnType; - this.parameters = new ArrayList<>(); - for (Parameter param : parameters) { - Parameter newParam = new Parameter(param); - this.parameters.add(newParam); - newParam.setMethod(this); - parameterCache.put(param.getLocalName(), param); - } - if (returnType != null) { - parameterCache.put(returnType.getLocalName(), returnType); - } - this.id = id; - } - - public final Parameter getFrame() { - return findParameter(FRAME_NAME); - } - - public void removeParameter(Parameter p) { - this.parameters.remove(p); - this.parameterCache.remove(p.getLocalName()); - p.setMethod(this); - } - - public void addParameter(int index, Parameter p) { - this.parameters.add(index, p); - this.parameterCache.put(p.getLocalName(), p); - p.setMethod(this); - } - - public String createReferenceName() { - if (getMethod() == null) { - return "-"; - } - return ElementUtils.createReferenceName(getMethod()); - } - - public int getNaturalOrder() { - return naturalOrder; - } - - public TemplateMethod(TemplateMethod method) { - this(method.id, method.naturalOrder, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); - getMessages().addAll(method.getMessages()); - } - - public TemplateMethod(TemplateMethod method, ExecutableElement executable) { - this(method.id, method.naturalOrder, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters); - getMessages().addAll(method.getMessages()); - } - - @Override - public Element getMessageElement() { - return method; - } - - @Override - public AnnotationMirror getMessageAnnotation() { - return markerAnnotation; - } - - @Override - protected List findChildContainers() { - return Collections.emptyList(); - } - - public void setId(String id) { - this.id = id; - } - - public String getId() { - return id; - } - - public Template getTemplate() { - return template; - } - - public MethodSpec getSpecification() { - return specification; - } - - public Parameter getReturnType() { - return returnType; - } - - public void replaceParameter(String localName, Parameter newParameter) { - if (returnType.getLocalName().equals(localName)) { - returnType = newParameter; - } else { - Parameter local = findParameter(localName); - int index = parameters.indexOf(local); - parameters.set(index, newParameter); - } - parameterCache.put(newParameter.getLocalName(), newParameter); - newParameter.setMethod(this); - } - - public Iterable getDynamicParameters() { - return new FilteredIterable<>(getParameters(), new Predicate() { - public boolean evaluate(Parameter value) { - return !value.getSpecification().isLocal() && !value.getSpecification().isAnnotated(); - } - }); - } - - public Iterable getSignatureParameters() { - return new FilteredIterable<>(getParameters(), new Predicate() { - public boolean evaluate(Parameter value) { - return value.getSpecification().isSignature(); - } - }); - } - - public List getParameters() { - return parameters; - } - - public Parameter findParameterOrDie(NodeExecutionData execution) { - for (Parameter parameter : parameters) { - if (parameter.getSpecification().isSignature() && parameter.getSpecification().getExecution() == execution) { - return parameter; - } - } - throw new AssertionError("Could not find parameter for execution"); - } - - public List findByExecutionData(NodeExecutionData execution) { - List foundParameters = new ArrayList<>(); - for (Parameter parameter : getParameters()) { - ParameterSpec spec = parameter.getSpecification(); - if (spec != null && spec.getExecution() != null && spec.getExecution().equals(execution) && parameter.getSpecification().isSignature()) { - foundParameters.add(parameter); - } - } - return foundParameters; - } - - public Parameter findParameter(String valueName) { - return parameterCache.get(valueName); - } - - public List getReturnTypeAndParameters() { - List allParameters = new ArrayList<>(getParameters().size() + 1); - if (getReturnType() != null) { - allParameters.add(getReturnType()); - } - allParameters.addAll(getParameters()); - return Collections.unmodifiableList(allParameters); - } - - public ExecutableElement getMethod() { - return method; - } - - public String getMethodName() { - if (getMethod() != null) { - return getMethod().getSimpleName().toString(); - } else { - return "$synthetic"; - } - } - - public AnnotationMirror getMarkerAnnotation() { - return markerAnnotation; - } - - @Override - public String toString() { - return String.format("%s [id = %s, method = %s]", getClass().getSimpleName(), getId(), getMethod()); - } - - public Parameter getPreviousParam(Parameter searchParam) { - Parameter prev = null; - for (Parameter param : getParameters()) { - if (param == searchParam) { - return prev; - } - prev = param; - } - return prev; - } - - @SuppressWarnings("unused") - public int getSignatureSize() { - int signatureSize = 0; - for (Parameter parameter : getSignatureParameters()) { - signatureSize++; - } - return signatureSize; - } - - public TypeSignature getTypeSignature() { - TypeSignature signature = new TypeSignature(); - signature.types.add(getReturnType().getType()); - for (Parameter parameter : getSignatureParameters()) { - TypeMirror typeData = parameter.getType(); - if (typeData != null) { - signature.types.add(typeData); - } - } - return signature; - } - - public void updateSignature(TypeSignature signature) { - // TODO(CH): fails in normal usage - output ok though - // assert signature.size() >= 1; - - int signatureIndex = 0; - for (Parameter parameter : getReturnTypeAndParameters()) { - if (!parameter.getSpecification().isSignature()) { - continue; - } - if (signatureIndex >= signature.size()) { - break; - } - TypeMirror newType = signature.get(signatureIndex++); - if (!ElementUtils.typeEquals(newType, parameter.getType())) { - replaceParameter(parameter.getLocalName(), new Parameter(parameter, newType)); - } - } - } - - @Override - public int compareTo(TemplateMethod o) { - if (this == o) { - return 0; - } - - int compare = compareBySignature(o); - if (compare == 0) { - // if signature sorting failed sort by id - compare = getId().compareTo(o.getId()); - } - if (compare == 0) { - // if still no difference sort by enclosing type name - TypeElement enclosingType1 = ElementUtils.findNearestEnclosingType(getMethod()); - TypeElement enclosingType2 = ElementUtils.findNearestEnclosingType(o.getMethod()); - compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString()); - } - return compare; - } - - public int compareBySignature(TemplateMethod compareMethod) { - List signature1 = getDynamicTypes(); - List signature2 = compareMethod.getDynamicTypes(); - - int result = 0; - for (int i = 0; i < Math.max(signature1.size(), signature2.size()); i++) { - TypeMirror t1 = i < signature1.size() ? signature1.get(i) : null; - TypeMirror t2 = i < signature2.size() ? signature2.get(i) : null; - result = ElementUtils.compareType(t1, t2); - if (result != 0) { - break; - } - } - - return result; - } - - public List getDynamicTypes() { - List types = new ArrayList<>(); - for (Parameter param : getDynamicParameters()) { - types.add(param.getType()); - } - return types; - } - - public static class TypeSignature implements Iterable { - - private final List types; - - public TypeSignature() { - this.types = new ArrayList<>(); - } - - public TypeSignature(List signature) { - this.types = signature; - } - - @Override - public int hashCode() { - return types.hashCode(); - } - - public int size() { - return types.size(); - } - - public TypeMirror get(int index) { - return types.get(index); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof TypeSignature) { - return ((TypeSignature) obj).types.equals(types); - } - return super.equals(obj); - } - - public Iterator iterator() { - return types.iterator(); - } - - @Override - public String toString() { - return types.toString(); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeCastData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeCastData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.type.*; - -public class TypeCastData extends TemplateMethod { - - private final TypeMirror targetType; - private final TypeMirror sourceType; - - public TypeCastData(TemplateMethod method, TypeMirror sourceType, TypeMirror targetType) { - super(method); - this.sourceType = sourceType; - this.targetType = targetType; - } - - public TypeMirror getSourceType() { - return sourceType; - } - - public TypeMirror getTargetType() { - return targetType; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeCheckData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeCheckData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import javax.lang.model.type.*; - -public class TypeCheckData extends TemplateMethod { - - private final TypeMirror checkedType; - private final TypeMirror valueType; - - public TypeCheckData(TemplateMethod method, TypeMirror checkedType, TypeMirror valueType) { - super(method); - this.checkedType = checkedType; - this.valueType = valueType; - } - - public TypeMirror getCheckedType() { - return checkedType; - } - - public TypeMirror getValueType() { - return valueType; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeSystemData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeSystemData.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.model; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; - -public class TypeSystemData extends Template { - - private final List implicitCasts = new ArrayList<>(); - private final List casts = new ArrayList<>(); - private final List checks = new ArrayList<>(); - private final List legacyTypes = new ArrayList<>(); - - private Set legacyTypeIds; - - private final boolean isDefault; - private final DSLOptions options; - - public TypeSystemData(ProcessorContext context, TypeElement templateType, AnnotationMirror annotation, DSLOptions options, boolean isDefault) { - super(context, templateType, annotation); - this.options = options; - this.isDefault = isDefault; - } - - public boolean isDefault() { - return isDefault; - } - - public DSLOptions getOptions() { - return options; - } - - @Override - public TypeSystemData getTypeSystem() { - return this; - } - - public List getLegacyTypes() { - return legacyTypes; - } - - public TypeCastData getCast(TypeMirror targetType) { - for (TypeCastData cast : casts) { - if (ElementUtils.typeEquals(cast.getTargetType(), targetType)) { - return cast; - } - } - return null; - } - - public TypeCheckData getCheck(TypeMirror type) { - for (TypeCheckData check : checks) { - if (ElementUtils.typeEquals(check.getCheckedType(), type)) { - return check; - } - } - return null; - } - - public List getImplicitCasts() { - return implicitCasts; - } - - public List getCasts() { - return casts; - } - - public List getChecks() { - return checks; - } - - @Override - protected List findChildContainers() { - List sinks = new ArrayList<>(); - if (checks != null) { - sinks.addAll(checks); - } - if (casts != null) { - sinks.addAll(casts); - } - if (implicitCasts != null) { - sinks.addAll(implicitCasts); - } - return sinks; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[template = " + ElementUtils.getSimpleName(getTemplateType()) + "]"; - } - - public List lookupByTargetType(TypeMirror targetType) { - if (getImplicitCasts() == null) { - return Collections.emptyList(); - } - List foundCasts = new ArrayList<>(); - for (ImplicitCastData cast : getImplicitCasts()) { - if (ElementUtils.typeEquals(cast.getTargetType(), targetType)) { - foundCasts.add(cast); - } - } - return foundCasts; - } - - public ImplicitCastData lookupCast(TypeMirror sourceType, TypeMirror targetType) { - if (getImplicitCasts() == null) { - return null; - } - for (ImplicitCastData cast : getImplicitCasts()) { - if (ElementUtils.typeEquals(cast.getSourceType(), sourceType) && ElementUtils.typeEquals(cast.getTargetType(), targetType)) { - return cast; - } - } - return null; - } - - public boolean hasImplicitSourceTypes(TypeMirror targetType) { - if (getImplicitCasts() == null) { - return false; - } - for (ImplicitCastData cast : getImplicitCasts()) { - if (ElementUtils.typeEquals(cast.getTargetType(), targetType)) { - return true; - } - } - return false; - } - - public List lookupTargetTypes() { - List sourceTypes = new ArrayList<>(); - for (ImplicitCastData cast : getImplicitCasts()) { - sourceTypes.add(cast.getTargetType()); - } - return ElementUtils.uniqueSortedTypes(sourceTypes, true); - } - - public List lookupSourceTypes(TypeMirror targetType) { - List sourceTypes = new ArrayList<>(); - sourceTypes.add(targetType); - for (ImplicitCastData cast : getImplicitCasts()) { - if (ElementUtils.typeEquals(cast.getTargetType(), targetType)) { - sourceTypes.add(cast.getSourceType()); - } - } - return ElementUtils.uniqueSortedTypes(sourceTypes, true); - } - - public boolean isImplicitSubtypeOf(TypeMirror source, TypeMirror target) { - List targetCasts = lookupByTargetType(target); - for (ImplicitCastData cast : targetCasts) { - if (ElementUtils.isSubtype(boxType(source), boxType(cast.getSourceType()))) { - return true; - } - } - return ElementUtils.isSubtype(boxType(source), boxType(target)); - } - - public TypeMirror boxType(TypeMirror type) { - return ElementUtils.boxType(getContext(), type); - } - - public boolean hasType(TypeMirror type) { - if (legacyTypeIds == null) { - legacyTypeIds = new HashSet<>(); - for (TypeMirror legacyType : legacyTypes) { - legacyTypeIds.add(ElementUtils.getTypeId(legacyType)); - } - } - return legacyTypeIds.contains(ElementUtils.getTypeId(type)); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/AbstractParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/AbstractParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +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.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.element.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.model.MessageContainer.Message; - -/** - * THIS IS NOT PUBLIC API. - */ -public abstract class AbstractParser { - - protected final ProcessorContext context; - protected final ProcessingEnvironment processingEnv; - - protected final Log log; - - public AbstractParser() { - this.context = ProcessorContext.getInstance(); - this.processingEnv = context.getEnvironment(); - this.log = context.getLog(); - } - - public final M parse(Element element) { - M model = null; - try { - AnnotationMirror mirror = null; - if (getAnnotationType() != null) { - mirror = ElementUtils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType()); - } - - if (!context.getTruffleTypes().verify(context, element, mirror)) { - return null; - } - model = parse(element, mirror); - if (model == null) { - return null; - } - - redirectMessages(new HashSet(), model, model); - model.emitMessages(context, log); - return filterErrorElements(model); - } catch (CompileErrorException e) { - log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage()); - return null; - } - } - - private void redirectMessages(Set visitedSinks, MessageContainer model, MessageContainer baseContainer) { - List messages = model.getMessages(); - for (int i = messages.size() - 1; i >= 0; i--) { - Message message = messages.get(i); - if (!ElementUtils.isEnclosedIn(baseContainer.getMessageElement(), message.getOriginalContainer().getMessageElement())) { - // redirect message - MessageContainer original = message.getOriginalContainer(); - String text = wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()); - Message redirectedMessage = new Message(null, null, baseContainer, text, message.getKind()); - model.getMessages().remove(i); - baseContainer.getMessages().add(redirectedMessage); - } - } - - for (MessageContainer childContainer : model) { - if (visitedSinks.contains(childContainer)) { - continue; - } - visitedSinks.add(childContainer); - - MessageContainer newBase = baseContainer; - if (childContainer.getBaseContainer() != null) { - newBase = childContainer.getBaseContainer(); - } - redirectMessages(visitedSinks, childContainer, newBase); - } - } - - private static String wrapText(Element element, AnnotationMirror mirror, String text) { - StringBuilder b = new StringBuilder(); - if (element != null) { - if (element.getKind() == ElementKind.METHOD) { - b.append("Method " + ElementUtils.createReferenceName((ExecutableElement) element)); - } else { - b.append("Element " + element.getSimpleName()); - } - } - if (mirror != null) { - b.append(" at annotation @" + ElementUtils.getSimpleName(mirror.getAnnotationType()).trim()); - } - - if (b.length() > 0) { - b.append(" is erroneous: ").append(text); - return b.toString(); - } else { - return text; - } - } - - protected M filterErrorElements(M model) { - return model.hasErrors() ? null : model; - } - - protected abstract M parse(Element element, AnnotationMirror mirror); - - public abstract Class getAnnotationType(); - - public boolean isDelegateToRootDeclaredType() { - return false; - } - - public List> getAllAnnotationTypes() { - List> list = new ArrayList<>(); - if (getAnnotationType() != null) { - list.add(getAnnotationType()); - } - list.addAll(getTypeDelegatedAnnotationTypes()); - return list; - } - - public List> getTypeDelegatedAnnotationTypes() { - return Collections.emptyList(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/CreateCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/CreateCastParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class CreateCastParser extends NodeMethodParser { - - public CreateCastParser(ProcessorContext context, NodeData operation) { - super(context, operation); - } - - @Override - public Class getAnnotationType() { - return CreateCast.class; - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - List childNames = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); - NodeChildData foundChild = null; - for (String childName : childNames) { - foundChild = getNode().findChild(childName); - if (foundChild != null) { - break; - } - } - TypeMirror baseType = getContext().getTruffleTypes().getNode(); - if (foundChild != null) { - baseType = foundChild.getOriginalType(); - } - - MethodSpec spec = new MethodSpec(new ParameterSpec("child", baseType)); - addDefaultFieldMethodSpec(spec); - ParameterSpec childSpec = new ParameterSpec("castedChild", baseType); - childSpec.setSignature(true); - spec.addRequired(childSpec); - return spec; - } - - @Override - public CreateCastData create(TemplateMethod method, boolean invalid) { - AnnotationMirror mirror = method.getMarkerAnnotation(); - List childNames = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); - CreateCastData cast = new CreateCastData(method, childNames); - AnnotationValue value = ElementUtils.getAnnotationValue(mirror, "value"); - TypeMirror type = null; - if (childNames == null || childNames.isEmpty()) { - cast.addError(value, "No value specified but required."); - return cast; - } - - for (String childName : childNames) { - NodeChildData child = getNode().findChild(childName); - if (child == null) { - // error - cast.addError(value, "Specified child '%s' not found.", childName); - continue; - } - if (type == null) { - type = child.getNodeType(); - } else if (!ElementUtils.typeEquals(type, child.getNodeType())) { - cast.addError(value, "All child nodes for a cast must have the same node type."); - continue; - } - } - return cast; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/FallbackParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/FallbackParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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.dsl.processor.parser; - -import java.lang.annotation.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; - -public class FallbackParser extends NodeMethodParser { - - public FallbackParser(ProcessorContext context, NodeData node) { - super(context, node); - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - return createDefaultMethodSpec(method, mirror, true, null); - } - - @Override - protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { - ParameterSpec parameterSpec = super.createValueParameterSpec(execution); - parameterSpec.setAllowSubclasses(false); - return parameterSpec; - } - - @Override - public SpecializationData create(TemplateMethod method, boolean invalid) { - return new SpecializationData(getNode(), method, SpecializationKind.FALLBACK); - } - - @Override - public Class getAnnotationType() { - return Fallback.class; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class ImplicitCastParser extends TypeSystemMethodParser { - - public ImplicitCastParser(ProcessorContext context, TypeSystemData typeSystem) { - super(context, typeSystem); - } - - @Override - public Class getAnnotationType() { - return ImplicitCast.class; - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - MethodSpec spec = new MethodSpec(new ParameterSpec("target", getContext().getType(Object.class))); - spec.addRequired(new ParameterSpec("source", getContext().getType(Object.class))).setSignature(true); - return spec; - } - - @Override - public ImplicitCastData create(TemplateMethod method, boolean invalid) { - if (invalid) { - return new ImplicitCastData(method, null, null); - } - - Parameter target = method.findParameter("targetValue"); - Parameter source = method.findParameter("sourceValue"); - - TypeMirror targetType = target.getType(); - TypeMirror sourceType = source.getType(); - - if (ElementUtils.typeEquals(targetType, sourceType)) { - method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName()); - } - - if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) { - method.addError("@%s annotated method %s must be static.", ImplicitCast.class.getSimpleName(), method.getMethodName()); - } - - return new ImplicitCastData(method, sourceType, targetType); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +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.dsl.processor.parser; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -public final class MethodSpecParser { - - private boolean emitErrors = true; - private boolean useVarArgs = false; - - private final Template template; - - public MethodSpecParser(Template template) { - this.template = template; - } - - public Template getTemplate() { - return template; - } - - public boolean isEmitErrors() { - return emitErrors; - } - - public boolean isUseVarArgs() { - return useVarArgs; - } - - public void setEmitErrors(boolean emitErrors) { - this.emitErrors = emitErrors; - } - - public void setUseVarArgs(boolean useVarArgs) { - this.useVarArgs = useVarArgs; - } - - public TemplateMethod parse(MethodSpec methodSpecification, ExecutableElement method, AnnotationMirror annotation, int naturalOrder) { - if (methodSpecification == null) { - return null; - } - - methodSpecification.applyTypeDefinitions("types"); - - String id = method.getSimpleName().toString(); - TypeMirror returnType = method.getReturnType(); - return parseImpl(methodSpecification, naturalOrder, id, method, annotation, returnType, method.getParameters()); - } - - public TemplateMethod parseImpl(MethodSpec methodSpecification, int naturalOrder, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, - List parameterTypes) { - ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); - Parameter returnTypeMirror = matchParameter(returnTypeSpec, new CodeVariableElement(returnType, "returnType"), -1, -1); - if (returnTypeMirror == null) { - if (isEmitErrors() && method != null) { - TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()); - String expectedReturnType = returnTypeSpec.toSignatureString(true); - String actualReturnType = ElementUtils.getSimpleName(returnType); - - String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, - methodSpecification.toSignatureString(method.getSimpleName().toString())); - invalidMethod.addError(message); - return invalidMethod; - } else { - return null; - } - } - - List parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method != null ? method.isVarArgs() : false); - if (parameters == null) { - if (isEmitErrors() && method != null) { - TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()); - String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(method), - methodSpecification.toSignatureString(method.getSimpleName().toString())); - invalidMethod.addError(message); - return invalidMethod; - } else { - return null; - } - } - - return new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, parameters); - } - - private static String createActualSignature(ExecutableElement method) { - StringBuilder b = new StringBuilder("("); - String sep = ""; - if (method != null) { - for (VariableElement var : method.getParameters()) { - b.append(sep); - b.append(ElementUtils.getSimpleName(var.asType())); - sep = ", "; - } - } - b.append(")"); - return b.toString(); - } - - /* - * Parameter parsing tries to parse required arguments starting from offset 0 with increasing - * offset until it finds a signature end that matches the required specification. If there is no - * end matching the required arguments, parsing fails. Parameters prior to the parsed required - * ones are cut and used to parse the optional parameters. - */ - private static List parseParameters(MethodSpec spec, List parameterTypes, boolean varArgs) { - List parsedRequired = null; - int offset = 0; - for (; offset <= parameterTypes.size(); offset++) { - List parameters = new ArrayList<>(); - parameters.addAll(parameterTypes.subList(offset, parameterTypes.size())); - parsedRequired = parseParametersRequired(spec, parameters, varArgs); - if (parsedRequired != null) { - break; - } - } - - if (parsedRequired == null) { - return null; - } - - if (parsedRequired.isEmpty() && offset == 0) { - offset = parameterTypes.size(); - } - List potentialOptionals = parameterTypes.subList(0, offset); - List parsedOptionals = parseParametersOptional(spec, potentialOptionals); - if (parsedOptionals == null) { - return null; - } - - List finalParameters = new ArrayList<>(); - finalParameters.addAll(parsedOptionals); - finalParameters.addAll(parsedRequired); - return finalParameters; - } - - private static List parseParametersOptional(MethodSpec spec, List types) { - List parsedParams = new ArrayList<>(); - - int typeStartIndex = 0; - List specifications = spec.getOptional(); - outer: for (int specIndex = 0; specIndex < specifications.size(); specIndex++) { - ParameterSpec specification = specifications.get(specIndex); - for (int typeIndex = typeStartIndex; typeIndex < types.size(); typeIndex++) { - VariableElement variable = types.get(typeIndex); - Parameter optionalParam = matchParameter(specification, variable, -1, -1); - if (optionalParam != null) { - parsedParams.add(optionalParam); - typeStartIndex = typeIndex + 1; - continue outer; - } - } - } - - if (typeStartIndex < types.size()) { - // not enough types found - return null; - } - return parsedParams; - } - - private static List parseParametersRequired(MethodSpec spec, List types, boolean typeVarArgs) { - List parsedParams = new ArrayList<>(); - List specifications = spec.getRequired(); - boolean specVarArgs = spec.isVariableRequiredParameters(); - int typeIndex = 0; - int specificationIndex = 0; - - ParameterSpec specification; - while ((specification = nextSpecification(specifications, specificationIndex, specVarArgs)) != null) { - VariableElement actualType = nextActualType(types, typeIndex, typeVarArgs); - if (actualType == null) { - if (spec.isIgnoreAdditionalSpecifications()) { - break; - } - return null; - } - - int typeVarArgsIndex = typeVarArgs ? typeIndex - types.size() + 1 : -1; - int specVarArgsIndex = specVarArgs ? specificationIndex - specifications.size() + 1 : -1; - - if (typeVarArgsIndex >= 0 && specVarArgsIndex >= 0) { - // both specifications and types have a variable number of arguments - // we would get into an endless loop if we would continue - break; - } - - Parameter resolvedParameter = matchParameter(specification, actualType, specVarArgsIndex, typeVarArgsIndex); - if (resolvedParameter == null) { - return null; - } - parsedParams.add(resolvedParameter); - typeIndex++; - specificationIndex++; - } - - // consume randomly ordered annotated parameters - VariableElement variable; - while ((variable = nextActualType(types, typeIndex, typeVarArgs)) != null) { - Parameter matchedParamter = matchAnnotatedParameter(spec, variable); - if (matchedParamter == null) { - break; - } - parsedParams.add(matchedParamter); - typeIndex++; - } - - if (typeIndex < types.size()) { - if (spec.isIgnoreAdditionalParameters()) { - return parsedParams; - } else { - return null; - } - } - - return parsedParams; - } - - private static Parameter matchAnnotatedParameter(MethodSpec spec, VariableElement variable) { - for (ParameterSpec parameterSpec : spec.getAnnotations()) { - if (parameterSpec.matches(variable)) { - Parameter matchedParameter = matchParameter(parameterSpec, variable, -1, -1); - if (matchedParameter != null) { - matchedParameter.setLocalName(variable.getSimpleName().toString()); - return matchedParameter; - } - } - } - return null; - } - - private static ParameterSpec nextSpecification(List specifications, int specIndex, boolean varArgs) { - if (varArgs && specIndex >= specifications.size() - 1 && !specifications.isEmpty()) { - return specifications.get(specifications.size() - 1); - } else if (specIndex < specifications.size()) { - return specifications.get(specIndex); - } else { - return null; - } - } - - private static VariableElement nextActualType(List types, int typeIndex, boolean varArgs) { - if (varArgs && typeIndex >= types.size() - 1 && !types.isEmpty()) { - // unpack varargs array argument - VariableElement actualType = types.get(types.size() - 1); - if (actualType.asType().getKind() == TypeKind.ARRAY) { - actualType = new CodeVariableElement(((ArrayType) actualType.asType()).getComponentType(), actualType.getSimpleName().toString()); - } - return actualType; - } else if (typeIndex < types.size()) { - return types.get(typeIndex); - } else { - return null; - } - } - - private static Parameter matchParameter(ParameterSpec specification, VariableElement variable, int specificationIndex, int varArgsIndex) { - TypeMirror resolvedType = variable.asType(); - if (hasError(resolvedType)) { - return null; - } - - if (!specification.matches(variable)) { - return null; - } - - return new Parameter(specification, variable, specificationIndex, varArgsIndex); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -public abstract class NodeMethodParser extends TemplateMethodParser { - - public NodeMethodParser(ProcessorContext context, NodeData node) { - super(context, node); - } - - public NodeData getNode() { - return template; - } - - protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { - ParameterSpec spec = new ParameterSpec(execution.getName(), getPossibleParameterTypes(execution)); - spec.setExecution(execution); - return spec; - } - - protected Collection getPossibleParameterTypes(NodeExecutionData execution) { - return getNode().getGenericTypes(execution); - } - - protected ParameterSpec createReturnParameterSpec() { - ParameterSpec returnValue = new ParameterSpec("returnValue", getPossibleReturnTypes()); - returnValue.setExecution(getNode().getThisExecution()); - return returnValue; - } - - protected Collection getPossibleReturnTypes() { - return Arrays.asList(getNode().getGenericType(getNode().getThisExecution())); - } - - @Override - public boolean isParsable(ExecutableElement method) { - if (getAnnotationType() != null) { - return ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null; - } - - return true; - } - - @SuppressWarnings("unused") - protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, boolean shortCircuitsEnabled, String shortCircuitName) { - MethodSpec methodSpec = new MethodSpec(createReturnParameterSpec()); - - addDefaultFrame(methodSpec); - addDefaultFieldMethodSpec(methodSpec); - addDefaultChildren(shortCircuitsEnabled, shortCircuitName, methodSpec); - - return methodSpec; - } - - private void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec spec) { - if (getNode().getChildren() == null) { - // children are null when parsing executable types - return; - } - - for (NodeExecutionData execution : getNode().getChildExecutions()) { - if (breakName != null && execution.getIndexedName().equals(breakName)) { - break; - } - - if (execution.isShortCircuit() && shortCircuitsEnabled) { - spec.addRequired(new ParameterSpec(shortCircuitValueName(execution.getName()), getContext().getType(boolean.class))); - } - spec.addRequired(createValueParameterSpec(execution)); - } - } - - protected void addDefaultFrame(MethodSpec methodSpec) { - if (getNode().supportsFrame()) { - methodSpec.addOptional(new ParameterSpec("frame", getNode().getFrameType())); - } - } - - protected void addDefaultFieldMethodSpec(MethodSpec methodSpec) { - for (NodeFieldData field : getNode().getFields()) { - if (field.getGetter() == null) { - ParameterSpec spec = new ParameterSpec(field.getName(), field.getType()); - spec.setLocal(true); - methodSpec.addOptional(spec); - } - } - } - - private static String shortCircuitValueName(String valueName) { - return "has" + ElementUtils.firstLetterUpperCase(valueName); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1680 +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.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.expression.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.java.compiler.*; -import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; -import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; - -@DSLOptions -public class NodeParser extends AbstractParser { - - public static final List> ANNOTATIONS = Arrays.asList(Fallback.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, NodeChild.class, - NodeChildren.class); - - @Override - protected NodeData parse(Element element, AnnotationMirror mirror) { - NodeData node = parseRootType((TypeElement) element); - if (Log.isDebug() && node != null) { - String dump = node.dump(); - log.message(Kind.ERROR, null, null, null, dump); - } - return node; - } - - @Override - protected NodeData filterErrorElements(NodeData model) { - for (Iterator iterator = model.getEnclosingNodes().iterator(); iterator.hasNext();) { - NodeData node = filterErrorElements(iterator.next()); - if (node == null) { - iterator.remove(); - } - } - if (model.hasErrors()) { - return null; - } - return model; - } - - @Override - public boolean isDelegateToRootDeclaredType() { - return true; - } - - @Override - public Class getAnnotationType() { - return null; - } - - @Override - public List> getTypeDelegatedAnnotationTypes() { - return ANNOTATIONS; - } - - private NodeData parseRootType(TypeElement rootType) { - List enclosedNodes = new ArrayList<>(); - for (TypeElement enclosedType : ElementFilter.typesIn(rootType.getEnclosedElements())) { - NodeData enclosedChild = parseRootType(enclosedType); - if (enclosedChild != null) { - enclosedNodes.add(enclosedChild); - } - } - NodeData node; - try { - node = parseNode(rootType); - } catch (CompileErrorException e) { - throw e; - } catch (Throwable e) { - RuntimeException e2 = new RuntimeException(String.format("Parsing of Node %s failed.", ElementUtils.getQualifiedName(rootType))); - e2.addSuppressed(e); - throw e2; - } - if (node == null && !enclosedNodes.isEmpty()) { - node = new NodeData(context, rootType); - } - - if (node != null) { - for (NodeData enclosedNode : enclosedNodes) { - node.addEnclosedNode(enclosedNode); - } - } - return node; - } - - private NodeData parseNode(TypeElement originalTemplateType) { - // reloading the type elements is needed for ecj - TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType)); - - if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) { - // generated nodes should not get called again. - return null; - } - - if (!ElementUtils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) { - return null; - } - - List lookupTypes = collectSuperClasses(new ArrayList(), templateType); - List members = loadMembers(templateType); - // ensure the processed element has at least one @Specialization annotation. - if (!containsSpecializations(members)) { - return null; - } - - NodeData node = parseNodeData(templateType, lookupTypes); - if (node.hasErrors()) { - return node; - } - - node.getFields().addAll(parseFields(lookupTypes, members)); - node.getChildren().addAll(parseChildren(lookupTypes, members)); - node.getChildExecutions().addAll(parseExecutions(node.getFields(), node.getChildren(), members)); - node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, node.getSignatureSize(), context.getFrameTypes(), false)); - - initializeExecutableTypes(node); - initializeImportGuards(node, lookupTypes, members); - initializeChildren(node); - - if (node.hasErrors()) { - return node; // error sync point - } - - if (node.hasErrors()) { - return node; // error sync point - } - - node.getSpecializations().addAll(new SpecializationMethodParser(context, node).parse(members)); - node.getSpecializations().addAll(new FallbackParser(context, node).parse(members)); - node.getCasts().addAll(new CreateCastParser(context, node).parse(members)); - node.getShortCircuits().addAll(new ShortCircuitParser(context, node).parse(members)); - - if (node.hasErrors()) { - return node; // error sync point - } - initializeSpecializations(members, node); - initializeExecutableTypeHierarchy(node); - - verifySpecializationSameLength(node); - initializeShortCircuits(node); // requires specializations and polymorphic specializations - - verifyVisibilities(node); - verifyMissingAbstractMethods(node, members); - verifyConstructors(node); - verifyNamingConvention(node.getShortCircuits(), "needs"); - verifySpecializationThrows(node); - return node; - } - - private static void initializeExecutableTypeHierarchy(NodeData node) { - SpecializationData polymorphic = node.getPolymorphicSpecialization(); - if (polymorphic != null) { - boolean polymorphicSignatureFound = false; - List dynamicTypes = polymorphic.getDynamicTypes(); - TypeMirror frame = null; - if (polymorphic.getFrame() != null) { - frame = dynamicTypes.remove(0); - } - - ExecutableTypeData polymorphicType = new ExecutableTypeData(node, polymorphic.getReturnType().getType(), "execute", frame, dynamicTypes); - String genericName = ExecutableTypeData.createName(polymorphicType) + "_"; - polymorphicType.setUniqueName(genericName); - - for (ExecutableTypeData type : node.getExecutableTypes()) { - if (polymorphicType.sameSignature(type)) { - polymorphicSignatureFound = true; - break; - } - } - - if (!polymorphicSignatureFound) { - node.getExecutableTypes().add(polymorphicType); - } - } - - List rootTypes = buildExecutableHierarchy(node); - List additionalAbstractRootTypes = new ArrayList<>(); - for (int i = 1; i < rootTypes.size(); i++) { - ExecutableTypeData rootType = rootTypes.get(i); - if (rootType.isAbstract()) { - // cannot implemement root - additionalAbstractRootTypes.add(rootType); - } else { - node.getExecutableTypes().remove(rootType); - } - } - if (!additionalAbstractRootTypes.isEmpty()) { - node.addError("Incompatible abstract execute methods found %s.", additionalAbstractRootTypes); - } - - namesUnique(node.getExecutableTypes()); - - } - - private static List buildExecutableHierarchy(NodeData node) { - List executes = node.getExecutableTypes(); - if (executes.isEmpty()) { - return Collections.emptyList(); - } - List hierarchyExecutes = new ArrayList<>(executes); - Collections.sort(hierarchyExecutes); - ExecutableTypeData parent = hierarchyExecutes.get(0); - ListIterator executesIterator = hierarchyExecutes.listIterator(1); - buildExecutableHierarchy(node, parent, executesIterator); - return hierarchyExecutes; - } - - private static void buildExecutableHierarchy(NodeData node, ExecutableTypeData parent, ListIterator executesIterator) { - while (executesIterator.hasNext()) { - ExecutableTypeData other = executesIterator.next(); - if (other.canDelegateTo(parent)) { - parent.addDelegatedFrom(other); - executesIterator.remove(); - } - } - for (int i = 1; i < parent.getDelegatedFrom().size(); i++) { - buildExecutableHierarchy(node, parent.getDelegatedFrom().get(i - 1), parent.getDelegatedFrom().listIterator(i)); - } - } - - private List loadMembers(TypeElement templateType) { - List members = new ArrayList<>(CompilerFactory.getCompiler(templateType).getAllMembersInDeclarationOrder(context.getEnvironment(), templateType)); - - return members; - } - - private boolean containsSpecializations(List elements) { - boolean foundSpecialization = false; - for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - if (ElementUtils.findAnnotationMirror(processingEnv, method, Specialization.class) != null) { - foundSpecialization = true; - break; - } - } - return foundSpecialization; - } - - private void initializeImportGuards(NodeData node, List lookupTypes, List elements) { - for (TypeElement lookupType : lookupTypes) { - AnnotationMirror importAnnotation = ElementUtils.findAnnotationMirror(processingEnv, lookupType, ImportStatic.class); - if (importAnnotation == null) { - continue; - } - AnnotationValue importClassesValue = ElementUtils.getAnnotationValue(importAnnotation, "value"); - List importClasses = ElementUtils.getAnnotationValueList(TypeMirror.class, importAnnotation, "value"); - if (importClasses.isEmpty()) { - node.addError(importAnnotation, importClassesValue, "At least import guard classes must be specified."); - continue; - } - for (TypeMirror importGuardClass : importClasses) { - if (importGuardClass.getKind() != TypeKind.DECLARED) { - node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' is not a declared type.", ElementUtils.getQualifiedName(importGuardClass)); - continue; - } - - TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass); - if (typeElement.getEnclosingElement().getKind().isClass() && !typeElement.getModifiers().contains(Modifier.PUBLIC)) { - node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' must be public.", ElementUtils.getQualifiedName(importGuardClass)); - continue; - } - elements.addAll(importPublicStaticMembers(typeElement, false)); - } - } - } - - private List importPublicStaticMembers(TypeElement importGuardClass, boolean includeConstructors) { - // hack to reload type is necessary for incremental compiling in eclipse. - // otherwise methods inside of import guard types are just not found. - TypeElement typeElement = ElementUtils.fromTypeMirror(context.reloadType(importGuardClass.asType())); - - List members = new ArrayList<>(); - for (Element importElement : processingEnv.getElementUtils().getAllMembers(typeElement)) { - if (!importElement.getModifiers().contains(Modifier.PUBLIC)) { - continue; - } - - if (includeConstructors && importElement.getKind() == ElementKind.CONSTRUCTOR) { - members.add(importElement); - } - - if (!importElement.getModifiers().contains(Modifier.STATIC)) { - continue; - } - - ElementKind kind = importElement.getKind(); - if (kind.isField() || kind == ElementKind.METHOD) { - members.add(importElement); - } - } - return members; - } - - private NodeData parseNodeData(TypeElement templateType, List typeHierarchy) { - AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class); - TypeSystemData typeSystem = null; - if (typeSystemMirror != null) { - TypeMirror typeSystemType = ElementUtils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value"); - typeSystem = (TypeSystemData) context.getTemplate(typeSystemType, true); - if (typeSystem == null) { - NodeData nodeData = new NodeData(context, templateType); - nodeData.addError("The used type system '%s' is invalid. Fix errors in the type system first.", ElementUtils.getQualifiedName(typeSystemType)); - return nodeData; - } - } else { - // default dummy type system - typeSystem = new TypeSystemData(context, templateType, null, NodeParser.class.getAnnotation(DSLOptions.class), true); - } - AnnotationMirror nodeInfoMirror = findFirstAnnotation(typeHierarchy, NodeInfo.class); - String shortName = null; - if (nodeInfoMirror != null) { - shortName = ElementUtils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"); - } - boolean useNodeFactory = findFirstAnnotation(typeHierarchy, GenerateNodeFactory.class) != null; - return new NodeData(context, templateType, shortName, typeSystem, useNodeFactory); - - } - - private List parseFields(List typeHierarchy, List elements) { - Set names = new HashSet<>(); - - List fields = new ArrayList<>(); - for (VariableElement field : ElementFilter.fieldsIn(elements)) { - if (field.getModifiers().contains(Modifier.STATIC)) { - continue; - } - if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) { - String name = field.getSimpleName().toString(); - fields.add(new NodeFieldData(field, null, field, false)); - names.add(name); - } - } - - List reversedTypeHierarchy = new ArrayList<>(typeHierarchy); - Collections.reverse(reversedTypeHierarchy); - for (TypeElement typeElement : reversedTypeHierarchy) { - AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, typeElement, NodeFields.class); - List children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", typeElement, NodeField.class); - - for (AnnotationMirror mirror : children) { - String name = ElementUtils.firstLetterLowerCase(ElementUtils.getAnnotationValue(String.class, mirror, "name")); - TypeMirror type = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "type"); - - NodeFieldData field = new NodeFieldData(typeElement, mirror, new CodeVariableElement(type, name), true); - if (name.isEmpty()) { - field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Field name cannot be empty."); - } else if (names.contains(name)) { - field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Duplicate field name '%s'.", name); - } - names.add(name); - - fields.add(field); - } - } - - for (NodeFieldData nodeFieldData : fields) { - nodeFieldData.setGetter(findGetter(elements, nodeFieldData.getName(), nodeFieldData.getType())); - } - - return fields; - } - - private List parseChildren(final List typeHierarchy, List elements) { - Set shortCircuits = new HashSet<>(); - for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); - if (mirror != null) { - shortCircuits.add(ElementUtils.getAnnotationValue(String.class, mirror, "value")); - } - } - Map castNodeTypes = new HashMap<>(); - for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, CreateCast.class); - if (mirror != null) { - List children = (ElementUtils.getAnnotationValueList(String.class, mirror, "value")); - if (children != null) { - for (String child : children) { - castNodeTypes.put(child, method.getReturnType()); - } - } - } - } - - List parsedChildren = new ArrayList<>(); - List typeHierarchyReversed = new ArrayList<>(typeHierarchy); - Collections.reverse(typeHierarchyReversed); - for (TypeElement type : typeHierarchyReversed) { - AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, type, NodeChildren.class); - - TypeMirror nodeClassType = type.getSuperclass(); - if (!ElementUtils.isAssignable(nodeClassType, context.getTruffleTypes().getNode())) { - nodeClassType = null; - } - - List children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class); - int index = 0; - for (AnnotationMirror childMirror : children) { - String name = ElementUtils.getAnnotationValue(String.class, childMirror, "value"); - if (name.equals("")) { - name = "child" + index; - } - - Cardinality cardinality = Cardinality.ONE; - - TypeMirror childType = inheritType(childMirror, "type", nodeClassType); - if (childType.getKind() == TypeKind.ARRAY) { - cardinality = Cardinality.MANY; - } - - TypeMirror originalChildType = childType; - TypeMirror castNodeType = castNodeTypes.get(name); - if (castNodeType != null) { - childType = castNodeType; - } - - Element getter = findGetter(elements, name, childType); - NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality); - - parsedChildren.add(nodeChild); - - if (nodeChild.getNodeType() == null) { - nodeChild.addError("No valid node type could be resoleved."); - } - if (nodeChild.hasErrors()) { - continue; - } - - index++; - } - } - - List filteredChildren = new ArrayList<>(); - Set encounteredNames = new HashSet<>(); - for (int i = parsedChildren.size() - 1; i >= 0; i--) { - NodeChildData child = parsedChildren.get(i); - if (!encounteredNames.contains(child.getName())) { - filteredChildren.add(0, child); - encounteredNames.add(child.getName()); - } - } - - return filteredChildren; - } - - private List parseExecutions(List fields, List children, List elements) { - // pre-parse short circuits - Set shortCircuits = new HashSet<>(); - List methods = ElementFilter.methodsIn(elements); - for (ExecutableElement method : methods) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); - if (mirror != null) { - shortCircuits.add(ElementUtils.getAnnotationValue(String.class, mirror, "value")); - } - } - - boolean hasVarArgs = false; - int maxSignatureSize = 0; - if (!children.isEmpty()) { - int lastIndex = children.size() - 1; - hasVarArgs = children.get(lastIndex).getCardinality() == Cardinality.MANY; - if (hasVarArgs) { - maxSignatureSize = lastIndex; - } else { - maxSignatureSize = children.size(); - } - } - - List nonGetterFields = new ArrayList<>(); - for (NodeFieldData field : fields) { - if (field.getGetter() == null && field.isGenerated()) { - nonGetterFields.add(field); - } - } - - TypeMirror cacheAnnotation = context.getType(Cached.class); - List frameTypes = context.getFrameTypes(); - // pre-parse specializations to find signature size - for (ExecutableElement method : methods) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, Specialization.class); - if (mirror == null) { - continue; - } - int currentArgumentIndex = 0; - boolean skipShortCircuit = false; - parameter: for (VariableElement var : method.getParameters()) { - if (skipShortCircuit) { - skipShortCircuit = false; - continue parameter; - } - - TypeMirror type = var.asType(); - if (currentArgumentIndex == 0) { - // skip optionals - for (TypeMirror frameType : frameTypes) { - if (ElementUtils.typeEquals(type, frameType)) { - continue parameter; - } - } - } - - if (currentArgumentIndex < nonGetterFields.size()) { - for (NodeFieldData field : nonGetterFields) { - if (ElementUtils.typeEquals(var.asType(), field.getType())) { - continue parameter; - } - } - } - - if (ElementUtils.findAnnotationMirror(var.getAnnotationMirrors(), cacheAnnotation) != null) { - continue parameter; - } - - int childIndex = currentArgumentIndex < children.size() ? currentArgumentIndex : children.size() - 1; - if (childIndex != -1) { - NodeChildData child = children.get(childIndex); - if (shortCircuits.contains(NodeExecutionData.createIndexedName(child, currentArgumentIndex - childIndex))) { - skipShortCircuit = true; - } - } - - currentArgumentIndex++; - } - maxSignatureSize = Math.max(maxSignatureSize, currentArgumentIndex); - } - - List executions = new ArrayList<>(); - for (int i = 0; i < maxSignatureSize; i++) { - boolean varArgParameter = false; - int childIndex = i; - if (i >= children.size() - 1) { - if (hasVarArgs) { - varArgParameter = hasVarArgs; - childIndex = Math.min(i, children.size() - 1); - } else if (i >= children.size()) { - childIndex = -1; - } - } - int varArgsIndex = -1; - boolean shortCircuit = false; - NodeChildData child = null; - if (childIndex != -1) { - varArgsIndex = varArgParameter ? Math.abs(childIndex - i) : -1; - child = children.get(childIndex); - shortCircuit = shortCircuits.contains(NodeExecutionData.createIndexedName(child, varArgsIndex)); - } - executions.add(new NodeExecutionData(child, i, varArgsIndex, shortCircuit)); - } - return executions; - } - - private List parseExecutableTypeData(NodeData node, List elements, int signatureSize, List frameTypes, boolean includeFinals) { - List typeData = new ArrayList<>(); - for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - Set modifiers = method.getModifiers(); - if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.STATIC)) { - continue; - } - if (!includeFinals && modifiers.contains(Modifier.FINAL)) { - continue; - } - - if (!method.getSimpleName().toString().startsWith("execute")) { - continue; - } - if (ElementUtils.findAnnotationMirror(context.getEnvironment(), method, Specialization.class) != null) { - continue; - } - - ExecutableTypeData executableType = new ExecutableTypeData(node, method, signatureSize, context.getFrameTypes()); - - if (executableType.getFrameParameter() != null) { - boolean supportedType = false; - for (TypeMirror type : frameTypes) { - if (ElementUtils.isAssignable(type, executableType.getFrameParameter())) { - supportedType = true; - break; - } - } - if (!supportedType) { - continue; - } - } - - typeData.add(executableType); - } - - namesUnique(typeData); - - return typeData; - } - - private static void namesUnique(List typeData) { - List names = new ArrayList<>(); - for (ExecutableTypeData type : typeData) { - names.add(type.getUniqueName()); - } - while (renameDuplicateIds(names)) { - // fix point - } - - for (int i = 0; i < typeData.size(); i++) { - typeData.get(i).setUniqueName(names.get(i)); - } - } - - private void initializeExecutableTypes(NodeData node) { - List allExecutes = node.getExecutableTypes(); - - Set inconsistentFrameTypes = new HashSet<>(); - TypeMirror frameType = null; - for (ExecutableTypeData execute : allExecutes) { - - TypeMirror frame = execute.getFrameParameter(); - TypeMirror resolvedFrameType; - if (frame != null) { - resolvedFrameType = frame; - if (frameType == null) { - frameType = resolvedFrameType; - } else if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) { - // found inconsistent frame types - inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType)); - inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType)); - } - } - } - if (!inconsistentFrameTypes.isEmpty()) { - // ensure they are sorted somehow - List inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes); - Collections.sort(inconsistentFrameTypesList); - node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList); - } - if (frameType == null) { - frameType = context.getType(void.class); - } - - node.setFrameType(frameType); - - boolean genericFound = false; - for (ExecutableTypeData type : node.getExecutableTypes()) { - if (!type.hasUnexpectedValue(context)) { - genericFound = true; - break; - } - } - - // no generic executes - if (!genericFound) { - node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the " - + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions."); - } - - int nodeChildDeclarations = 0; - int nodeChildDeclarationsRequired = 0; - List executions = node.getChildExecutions(); - for (NodeExecutionData execution : executions) { - if (execution.getChild() == null) { - nodeChildDeclarationsRequired = execution.getIndex() + 1; - } else { - nodeChildDeclarations++; - } - } - - List requireNodeChildDeclarations = new ArrayList<>(); - for (ExecutableTypeData type : allExecutes) { - if (type.getEvaluatedCount() < nodeChildDeclarationsRequired) { - requireNodeChildDeclarations.add(ElementUtils.createReferenceName(type.getMethod())); - } - } - - if (!requireNodeChildDeclarations.isEmpty()) { - node.addError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " - + "The following execute methods do not provide all evaluated values for the expected signature size %s: %s.", executions.size(), requireNodeChildDeclarations); - } - - if (nodeChildDeclarations > 0 && executions.size() == node.getMinimalEvaluatedParameters()) { - for (NodeChildData child : node.getChildren()) { - child.addError("Unnecessary @NodeChild declaration. All evaluated child values are provided as parameters in execute methods."); - } - } - - } - - private void initializeChildren(NodeData node) { - initializeExecuteWith(node); - - for (NodeChildData child : node.getChildren()) { - TypeMirror nodeType = child.getNodeType(); - NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType)); - - child.setNode(fieldNodeData); - if (fieldNodeData == null || fieldNodeData.hasErrors()) { - child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType)); - } else { - List types = child.findGenericExecutableTypes(context); - if (types.isEmpty()) { - AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); - child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s and frame types %s.", child.getExecuteWith().size(), - ElementUtils.getSimpleName(nodeType), ElementUtils.getUniqueIdentifiers(createAllowedChildFrameTypes(node))); - } - } - } - } - - private static void initializeExecuteWith(NodeData node) { - for (NodeChildData child : node.getChildren()) { - List executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); - AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); - List executeWith = new ArrayList<>(); - for (String executeWithString : executeWithStrings) { - if (child.getName().equals(executeWithString)) { - child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString); - continue; - } - NodeExecutionData found = null; - boolean before = true; - for (NodeExecutionData resolveChild : node.getChildExecutions()) { - if (resolveChild.getChild() == child) { - before = false; - continue; - } - if (resolveChild.getIndexedName().equals(executeWithString)) { - found = resolveChild; - break; - } - } - - if (found == null) { - child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString); - continue; - } else if (!before) { - child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, - executeWithString); - continue; - } - executeWith.add(found); - } - child.setExecuteWith(executeWith); - } - } - - private NodeData parseChildNodeData(NodeData parentNode, NodeChildData child, TypeElement originalTemplateType) { - TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType)); - - if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) { - // generated nodes should not get called again. - return null; - } - - if (!ElementUtils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) { - return null; - } - - List lookupTypes = collectSuperClasses(new ArrayList(), templateType); - - // Declaration order is not required for child nodes. - List members = processingEnv.getElementUtils().getAllMembers(templateType); - NodeData node = parseNodeData(templateType, lookupTypes); - if (node.hasErrors()) { - return node; - } - List frameTypes = Collections.emptyList(); - if (parentNode.getFrameType() != null) { - frameTypes = Arrays.asList(parentNode.getFrameType()); - } - node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, child.getExecuteWith().size(), frameTypes, true)); - node.setFrameType(parentNode.getFrameType()); - return node; - } - - private List createAllowedChildFrameTypes(NodeData parentNode) { - List allowedFrameTypes = new ArrayList<>(); - for (TypeMirror frameType : context.getFrameTypes()) { - if (ElementUtils.isAssignable(parentNode.getFrameType(), frameType)) { - allowedFrameTypes.add(frameType); - } - } - return allowedFrameTypes; - } - - private void initializeSpecializations(List elements, final NodeData node) { - if (node.getSpecializations().isEmpty()) { - return; - } - - initializeExpressions(elements, node); - - if (node.hasErrors()) { - return; - } - - initializeGeneric(node); - initializeUninitialized(node); - initializeOrder(node); - initializePolymorphism(node); // requires specializations - initializeReachability(node); - initializeContains(node); - resolveContains(node); - - List specializations = node.getSpecializations(); - for (SpecializationData cur : specializations) { - for (SpecializationData contained : cur.getContains()) { - if (contained != cur) { - contained.getExcludedBy().add(cur); - } - } - } - - initializeSpecializationIdsWithMethodNames(node.getSpecializations()); - } - - private static void initializeOrder(NodeData node) { - List specializations = node.getSpecializations(); - Collections.sort(specializations); - - for (SpecializationData specialization : specializations) { - String searchName = specialization.getInsertBeforeName(); - if (searchName == null || specialization.getMethod() == null) { - continue; - } - SpecializationData found = lookupSpecialization(node, searchName); - if (found == null || found.getMethod() == null) { - AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore"); - specialization.addError(value, "The referenced specialization '%s' could not be found.", searchName); - continue; - } - - ExecutableElement currentMethod = specialization.getMethod(); - ExecutableElement insertBeforeMethod = found.getMethod(); - - TypeMirror currentEnclosedType = currentMethod.getEnclosingElement().asType(); - TypeMirror insertBeforeEnclosedType = insertBeforeMethod.getEnclosingElement().asType(); - - if (ElementUtils.typeEquals(currentEnclosedType, insertBeforeEnclosedType) || !ElementUtils.isSubtype(currentEnclosedType, insertBeforeEnclosedType)) { - AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore"); - specialization.addError(value, "Specializations can only be inserted before specializations in superclasses.", searchName); - continue; - } - - specialization.setInsertBefore(found); - } - - for (int i = 0; i < specializations.size(); i++) { - SpecializationData specialization = specializations.get(i); - SpecializationData insertBefore = specialization.getInsertBefore(); - if (insertBefore != null) { - int insertIndex = specializations.indexOf(insertBefore); - if (insertIndex < i) { - specializations.remove(i); - specializations.add(insertIndex, specialization); - } - } - } - - for (int i = 0; i < specializations.size(); i++) { - specializations.get(i).setIndex(i); - } - } - - private static void initializeContains(NodeData node) { - for (SpecializationData specialization : node.getSpecializations()) { - Set resolvedSpecializations = specialization.getContains(); - resolvedSpecializations.clear(); - Set includeNames = specialization.getContainsNames(); - for (String includeName : includeNames) { - // TODO reduce complexity of this lookup. - SpecializationData foundSpecialization = lookupSpecialization(node, includeName); - - if (foundSpecialization == null) { - AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); - specialization.addError(value, "The referenced specialization '%s' could not be found.", includeName); - } else { - if (foundSpecialization.compareTo(specialization) > 0) { - AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); - if (foundSpecialization.compareTo(specialization) > 0) { - specialization.addError(value, "The contained specialization '%s' must be declared before the containing specialization.", includeName); - } - - } - resolvedSpecializations.add(foundSpecialization); - } - } - } - } - - private void resolveContains(NodeData node) { - // flatten transitive includes - for (SpecializationData specialization : node.getSpecializations()) { - if (specialization.getContains().isEmpty()) { - continue; - } - Set foundSpecializations = new HashSet<>(); - collectIncludes(specialization, foundSpecializations, new HashSet()); - specialization.getContains().addAll(foundSpecializations); - } - } - - private static SpecializationData lookupSpecialization(NodeData node, String includeName) { - SpecializationData foundSpecialization = null; - for (SpecializationData searchSpecialization : node.getSpecializations()) { - if (searchSpecialization.getMethodName().equals(includeName)) { - foundSpecialization = searchSpecialization; - break; - } - } - return foundSpecialization; - } - - private void collectIncludes(SpecializationData specialization, Set found, Set visited) { - if (visited.contains(specialization)) { - // circle found - specialization.addError("Circular contained specialization '%s' found.", specialization.createReferenceName()); - return; - } - visited.add(specialization); - - for (SpecializationData included : specialization.getContains()) { - collectIncludes(included, found, new HashSet<>(visited)); - found.add(included); - } - } - - private static void initializeReachability(final NodeData node) { - List specializations = node.getSpecializations(); - for (int i = specializations.size() - 1; i >= 0; i--) { - SpecializationData current = specializations.get(i); - if (current.isPolymorphic()) { - current.setReachable(true); - continue; - } - - List shadowedBy = null; - for (int j = i - 1; j >= 0; j--) { - SpecializationData prev = specializations.get(j); - if (prev.isPolymorphic()) { - continue; - } - if (!current.isReachableAfter(prev)) { - if (shadowedBy == null) { - shadowedBy = new ArrayList<>(); - } - shadowedBy.add(prev); - } - } - - if (shadowedBy != null) { - StringBuilder name = new StringBuilder(); - String sep = ""; - for (SpecializationData shadowSpecialization : shadowedBy) { - name.append(sep); - name.append(shadowSpecialization.createReferenceName()); - sep = ", "; - } - current.addError("%s is not reachable. It is shadowed by %s.", current.isFallback() ? "Generic" : "Specialization", name); - } - current.setReachable(shadowedBy == null); - } - } - - private static void initializeSpecializationIdsWithMethodNames(List specializations) { - List signatures = new ArrayList<>(); - for (SpecializationData specialization : specializations) { - if (specialization.isFallback()) { - signatures.add("Fallback"); - } else if (specialization.isUninitialized()) { - signatures.add("Uninitialized"); - } else if (specialization.isPolymorphic()) { - signatures.add("Polymorphic"); - } else { - String name = specialization.getMethodName(); - - // hack for name clashes with BaseNode. - if (name.equalsIgnoreCase("base")) { - name = name + "0"; - } else if (name.startsWith("do")) { - String filteredDo = name.substring(2, name.length()); - if (!filteredDo.isEmpty() && Character.isJavaIdentifierStart(filteredDo.charAt(0))) { - name = filteredDo; - } - } - signatures.add(ElementUtils.firstLetterUpperCase(name)); - } - } - - while (renameDuplicateIds(signatures)) { - // fix point - } - - for (int i = 0; i < specializations.size(); i++) { - specializations.get(i).setId(signatures.get(i)); - } - } - - private static boolean renameDuplicateIds(List signatures) { - boolean changed = false; - Map counts = new HashMap<>(); - for (String s1 : signatures) { - Integer count = counts.get(s1.toLowerCase()); - if (count == null) { - count = 0; - } - count++; - counts.put(s1.toLowerCase(), count); - } - - for (String s : counts.keySet()) { - int count = counts.get(s); - if (count > 1) { - changed = true; - int number = 0; - for (ListIterator iterator = signatures.listIterator(); iterator.hasNext();) { - String s2 = iterator.next(); - if (s.equalsIgnoreCase(s2)) { - iterator.set(s2 + number); - number++; - } - } - } - } - return changed; - } - - private void initializeExpressions(List elements, NodeData node) { - List members = filterNotAccessibleElements(node.getTemplateType(), elements); - - List fields = new ArrayList<>(); - for (NodeFieldData field : node.getFields()) { - fields.add(field.getVariable()); - } - - for (SpecializationData specialization : node.getSpecializations()) { - if (specialization.getMethod() == null) { - continue; - } - - List specializationMembers = new ArrayList<>(members.size() + specialization.getParameters().size() + fields.size()); - for (Parameter p : specialization.getParameters()) { - specializationMembers.add(p.getVariableElement()); - } - specializationMembers.addAll(fields); - specializationMembers.addAll(members); - DSLExpressionResolver resolver = new DSLExpressionResolver(context, specializationMembers); - - initializeCaches(specialization, resolver); - initializeGuards(specialization, resolver); - if (specialization.hasErrors()) { - continue; - } - initializeLimit(specialization, resolver); - initializeAssumptions(specialization, resolver); - } - } - - private void initializeAssumptions(SpecializationData specialization, DSLExpressionResolver resolver) { - final DeclaredType assumptionType = context.getDeclaredType(Assumption.class); - final TypeMirror assumptionArrayType = new ArrayCodeTypeMirror(assumptionType); - final List assumptionDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "assumptions"); - List assumptionExpressions = new ArrayList<>(); - int assumptionId = 0; - for (String assumption : assumptionDefinitions) { - AssumptionExpression assumptionExpression; - DSLExpression expression = null; - try { - expression = DSLExpression.parse(assumption); - expression.accept(resolver); - assumptionExpression = new AssumptionExpression(specialization, expression, "assumption" + assumptionId); - if (!ElementUtils.isAssignable(expression.getResolvedType(), assumptionType) && !ElementUtils.isAssignable(expression.getResolvedType(), assumptionArrayType)) { - assumptionExpression.addError("Incompatible return type %s. Assumptions must be assignable to %s or %s.", ElementUtils.getSimpleName(expression.getResolvedType()), - ElementUtils.getSimpleName(assumptionType), ElementUtils.getSimpleName(assumptionArrayType)); - } - if (specialization.isDynamicParameterBound(expression)) { - specialization.addError("Assumption expressions must not bind dynamic parameter values."); - } - } catch (InvalidExpressionException e) { - assumptionExpression = new AssumptionExpression(specialization, null, "assumption" + assumptionId); - assumptionExpression.addError("Error parsing expression '%s': %s", assumption, e.getMessage()); - } - assumptionExpressions.add(assumptionExpression); - } - specialization.setAssumptionExpressions(assumptionExpressions); - } - - private void initializeLimit(SpecializationData specialization, DSLExpressionResolver resolver) { - AnnotationValue annotationValue = ElementUtils.getAnnotationValue(specialization.getMessageAnnotation(), "limit"); - - String limitValue; - if (annotationValue == null) { - limitValue = ""; - } else { - limitValue = (String) annotationValue.getValue(); - } - if (limitValue.isEmpty()) { - limitValue = "3"; - } else if (!specialization.hasMultipleInstances()) { - specialization.addWarning(annotationValue, "The limit expression has no effect. Multiple specialization instantiations are impossible for this specialization."); - return; - } - - TypeMirror expectedType = context.getType(int.class); - try { - DSLExpression expression = DSLExpression.parse(limitValue); - expression.accept(resolver); - if (!ElementUtils.typeEquals(expression.getResolvedType(), expectedType)) { - specialization.addError(annotationValue, "Incompatible return type %s. Limit expressions must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), - ElementUtils.getSimpleName(expectedType)); - } - if (specialization.isDynamicParameterBound(expression)) { - specialization.addError(annotationValue, "Limit expressions must not bind dynamic parameter values."); - } - - specialization.setLimitExpression(expression); - } catch (InvalidExpressionException e) { - specialization.addError(annotationValue, "Error parsing expression '%s': %s", limitValue, e.getMessage()); - } - } - - private void initializeCaches(SpecializationData specialization, DSLExpressionResolver resolver) { - TypeMirror cacheMirror = context.getType(Cached.class); - List expressions = new ArrayList<>(); - for (Parameter parameter : specialization.getParameters()) { - AnnotationMirror annotationMirror = ElementUtils.findAnnotationMirror(parameter.getVariableElement().getAnnotationMirrors(), cacheMirror); - if (annotationMirror != null) { - String initializer = ElementUtils.getAnnotationValue(String.class, annotationMirror, "value"); - - TypeMirror parameterType = parameter.getType(); - - DSLExpressionResolver localResolver = resolver; - if (parameterType.getKind() == TypeKind.DECLARED) { - localResolver = localResolver.copy(importPublicStaticMembers(ElementUtils.fromTypeMirror(parameterType), true)); - } - - CacheExpression cacheExpression; - DSLExpression expression = null; - try { - expression = DSLExpression.parse(initializer); - expression.accept(localResolver); - cacheExpression = new CacheExpression(parameter, annotationMirror, expression); - if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) { - cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), - ElementUtils.getSimpleName(parameter.getType())); - } - } catch (InvalidExpressionException e) { - cacheExpression = new CacheExpression(parameter, annotationMirror, null); - cacheExpression.addError("Error parsing expression '%s': %s", initializer, e.getMessage()); - } - expressions.add(cacheExpression); - } - } - specialization.setCaches(expressions); - - if (specialization.hasErrors()) { - return; - } - - // verify that cache expressions are bound in the correct order. - for (int i = 0; i < expressions.size(); i++) { - CacheExpression currentExpression = expressions.get(i); - Set boundVariables = currentExpression.getExpression().findBoundVariableElements(); - for (int j = i + 1; j < expressions.size(); j++) { - CacheExpression boundExpression = expressions.get(j); - if (boundVariables.contains(boundExpression.getParameter().getVariableElement())) { - currentExpression.addError("The initializer expression of parameter '%s' binds unitialized parameter '%s. Reorder the parameters to resolve the problem.", - currentExpression.getParameter().getLocalName(), boundExpression.getParameter().getLocalName()); - break; - } - } - } - } - - private void initializeGuards(SpecializationData specialization, DSLExpressionResolver resolver) { - final TypeMirror booleanType = context.getType(boolean.class); - List guardDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); - List guardExpressions = new ArrayList<>(); - for (String guard : guardDefinitions) { - GuardExpression guardExpression; - DSLExpression expression = null; - try { - expression = DSLExpression.parse(guard); - expression.accept(resolver); - guardExpression = new GuardExpression(specialization, expression); - if (!ElementUtils.typeEquals(expression.getResolvedType(), booleanType)) { - guardExpression.addError("Incompatible return type %s. Guards must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(booleanType)); - } - } catch (InvalidExpressionException e) { - guardExpression = new GuardExpression(specialization, null); - guardExpression.addError("Error parsing expression '%s': %s", guard, e.getMessage()); - } - guardExpressions.add(guardExpression); - } - specialization.setGuards(guardExpressions); - } - - private static List filterNotAccessibleElements(TypeElement templateType, List elements) { - String packageName = ElementUtils.getPackageName(templateType); - List filteredElements = new ArrayList<>(elements); - for (Element element : elements) { - Modifier visibility = ElementUtils.getVisibility(element.getModifiers()); - if (visibility == Modifier.PRIVATE) { - continue; - } else if (visibility == null) { - String elementPackageName = ElementUtils.getPackageName(element.getEnclosingElement().asType()); - if (!Objects.equals(packageName, elementPackageName) && !elementPackageName.equals("java.lang")) { - continue; - } - } - - filteredElements.add(element); - } - return filteredElements; - } - - private void initializeGeneric(final NodeData node) { - List generics = new ArrayList<>(); - for (SpecializationData spec : node.getSpecializations()) { - if (spec.isFallback()) { - generics.add(spec); - } - } - - if (generics.size() == 1 && node.getSpecializations().size() == 1) { - // TODO this limitation should be lifted - for (SpecializationData generic : generics) { - generic.addError("@%s defined but no @%s.", Fallback.class.getSimpleName(), Specialization.class.getSimpleName()); - } - } - - if (generics.isEmpty()) { - node.getSpecializations().add(createGenericSpecialization(node)); - } else { - if (generics.size() > 1) { - for (SpecializationData generic : generics) { - generic.addError("Only one @%s is allowed per operation.", Fallback.class.getSimpleName()); - } - } - } - } - - private SpecializationData createGenericSpecialization(final NodeData node) { - FallbackParser parser = new FallbackParser(context, node); - MethodSpec specification = parser.createDefaultMethodSpec(node.getSpecializations().iterator().next().getMethod(), null, true, null); - - List parameterTypes = new ArrayList<>(); - int signatureIndex = 1; - for (ParameterSpec spec : specification.getRequired()) { - parameterTypes.add(new CodeVariableElement(createGenericType(node, spec), "arg" + signatureIndex)); - if (spec.isSignature()) { - signatureIndex++; - } - } - - TypeMirror returnType = createGenericType(node, specification.getReturnType()); - SpecializationData generic = parser.create("Generic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, parameterTypes); - if (generic == null) { - throw new RuntimeException("Unable to create generic signature for node " + node.getNodeId() + " with " + parameterTypes + ". Specification " + specification + "."); - } - - return generic; - } - - private TypeMirror createGenericType(NodeData node, ParameterSpec spec) { - NodeExecutionData execution = spec.getExecution(); - Collection allowedTypes; - if (execution == null) { - allowedTypes = spec.getAllowedTypes(); - } else { - allowedTypes = Arrays.asList(node.getGenericType(execution)); - } - if (allowedTypes.size() == 1) { - return allowedTypes.iterator().next(); - } else { - return ElementUtils.getCommonSuperType(context, allowedTypes); - } - } - - private static void initializeUninitialized(final NodeData node) { - SpecializationData generic = node.getGenericSpecialization(); - if (generic == null) { - return; - } - TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", -1, node, generic.getSpecification(), null, null, generic.getReturnType(), generic.getParameters()); - // should not use messages from generic specialization - uninializedMethod.getMessages().clear(); - node.getSpecializations().add(new SpecializationData(node, uninializedMethod, SpecializationKind.UNINITIALIZED)); - } - - private void initializePolymorphism(NodeData node) { - if (!node.needsRewrites(context)) { - return; - } - - SpecializationData generic = node.getGenericSpecialization(); - List types = new ArrayList<>(); - - Collection frameTypes = new HashSet<>(); - for (SpecializationData specialization : node.getSpecializations()) { - if (specialization.getFrame() != null) { - frameTypes.add(specialization.getFrame().getType()); - } - } - if (node.supportsFrame()) { - frameTypes.add(node.getFrameType()); - } - - if (!frameTypes.isEmpty()) { - frameTypes = ElementUtils.uniqueSortedTypes(frameTypes, false); - TypeMirror frameType; - if (frameTypes.size() == 1) { - frameType = frameTypes.iterator().next(); - } else { - frameType = context.getType(Frame.class); - } - types.add(new CodeVariableElement(frameType, TemplateMethod.FRAME_NAME)); - } - - TypeMirror returnType = null; - int index = 0; - for (Parameter genericParameter : generic.getReturnTypeAndParameters()) { - TypeMirror polymorphicType; - if (genericParameter.getLocalName().equals(TemplateMethod.FRAME_NAME)) { - continue; - } - boolean isReturnParameter = genericParameter == generic.getReturnType(); - if (!genericParameter.getSpecification().isSignature()) { - polymorphicType = genericParameter.getType(); - } else { - Collection usedTypes = new HashSet<>(); - for (SpecializationData specialization : node.getSpecializations()) { - if (specialization.isUninitialized()) { - continue; - } - Parameter parameter = specialization.findParameter(genericParameter.getLocalName()); - if (parameter == specialization.getReturnType() && specialization.isFallback() && specialization.getMethod() == null) { - continue; - } - if (parameter == null) { - throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName()); - } - usedTypes.add(parameter.getType()); - } - usedTypes = ElementUtils.uniqueSortedTypes(usedTypes, false); - - if (usedTypes.size() == 1) { - polymorphicType = usedTypes.iterator().next(); - } else { - polymorphicType = ElementUtils.getCommonSuperType(context, usedTypes); - } - - NodeExecutionData execution = genericParameter.getSpecification().getExecution(); - if (execution != null && !ElementUtils.isSubtypeBoxed(context, polymorphicType, node.getGenericType(execution))) { - throw new AssertionError(String.format("Polymorphic types %s not compatible to generic type %s.", polymorphicType, node.getGenericType(execution))); - } - - } - if (isReturnParameter) { - returnType = polymorphicType; - } else { - types.add(new CodeVariableElement(polymorphicType, "param" + index)); - } - index++; - } - - SpecializationMethodParser parser = new SpecializationMethodParser(context, node); - SpecializationData polymorphic = parser.create("Polymorphic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, types); - if (polymorphic == null) { - throw new AssertionError("Failed to parse polymorphic signature. " + parser.createDefaultMethodSpec(null, null, false, null) + " Types: " + returnType + " - " + types); - } - - polymorphic.setKind(SpecializationKind.POLYMORPHIC); - node.getSpecializations().add(polymorphic); - } - - private void initializeShortCircuits(NodeData node) { - Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits()); - - boolean valid = true; - List shortCircuitExecutions = new ArrayList<>(); - for (NodeExecutionData execution : node.getChildExecutions()) { - if (!execution.isShortCircuit()) { - continue; - } - shortCircuitExecutions.add(execution); - String valueName = execution.getIndexedName(); - List availableCircuits = groupedShortCircuits.get(valueName); - - if (availableCircuits == null || availableCircuits.isEmpty()) { - node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); - valid = false; - continue; - } - - boolean sameMethodName = true; - String methodName = availableCircuits.get(0).getMethodName(); - for (ShortCircuitData circuit : availableCircuits) { - if (!circuit.getMethodName().equals(methodName)) { - sameMethodName = false; - } - } - - if (!sameMethodName) { - for (ShortCircuitData circuit : availableCircuits) { - circuit.addError("All short circuits for short cut value '%s' must have the same method name.", valueName); - } - valid = false; - continue; - } - - ShortCircuitData genericCircuit = null; - for (ShortCircuitData circuit : availableCircuits) { - if (isGenericShortCutMethod(circuit)) { - genericCircuit = circuit; - break; - } - } - - if (genericCircuit == null) { - node.addError("No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName); - valid = false; - continue; - } - - for (ShortCircuitData circuit : availableCircuits) { - if (circuit != genericCircuit) { - circuit.setGenericShortCircuitMethod(genericCircuit); - } - } - } - - if (!valid) { - return; - } - - List specializations = new ArrayList<>(); - specializations.addAll(node.getSpecializations()); - for (SpecializationData specialization : specializations) { - List assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); - - for (NodeExecutionData shortCircuit : shortCircuitExecutions) { - List availableShortCuts = groupedShortCircuits.get(shortCircuit.getIndexedName()); - - ShortCircuitData genericShortCircuit = null; - ShortCircuitData compatibleShortCircuit = null; - for (ShortCircuitData circuit : availableShortCuts) { - if (circuit.isGeneric()) { - genericShortCircuit = circuit; - } else if (circuit.isCompatibleTo(specialization)) { - compatibleShortCircuit = circuit; - } - } - - if (compatibleShortCircuit == null) { - compatibleShortCircuit = genericShortCircuit; - } - assignedShortCuts.add(compatibleShortCircuit); - } - specialization.setShortCircuits(assignedShortCuts); - } - } - - private boolean isGenericShortCutMethod(ShortCircuitData method) { - for (Parameter parameter : method.getParameters()) { - NodeExecutionData execution = parameter.getSpecification().getExecution(); - if (execution == null) { - continue; - } - ExecutableTypeData found = null; - List executableElements = execution.getChild().findGenericExecutableTypes(context); - for (ExecutableTypeData executable : executableElements) { - if (ElementUtils.typeEquals(executable.getReturnType(), parameter.getType())) { - found = executable; - break; - } - } - if (found == null) { - return false; - } - } - return true; - } - - private static Map> groupShortCircuits(List shortCircuits) { - Map> group = new HashMap<>(); - for (ShortCircuitData shortCircuit : shortCircuits) { - List circuits = group.get(shortCircuit.getValueName()); - if (circuits == null) { - circuits = new ArrayList<>(); - group.put(shortCircuit.getValueName(), circuits); - } - circuits.add(shortCircuit); - } - return group; - } - - private static boolean verifySpecializationSameLength(NodeData nodeData) { - int lastArgs = -1; - for (SpecializationData specializationData : nodeData.getSpecializations()) { - int signatureArgs = specializationData.getSignatureSize(); - if (lastArgs == signatureArgs) { - continue; - } - if (lastArgs != -1) { - for (SpecializationData specialization : nodeData.getSpecializations()) { - specialization.addError("All specializations must have the same number of arguments."); - } - return false; - } else { - lastArgs = signatureArgs; - } - } - return true; - } - - private static void verifyVisibilities(NodeData node) { - if (node.getTemplateType().getModifiers().contains(Modifier.PRIVATE) && node.getSpecializations().size() > 0) { - node.addError("Classes containing a @%s annotation must not be private.", Specialization.class.getSimpleName()); - } - } - - private static void verifyMissingAbstractMethods(NodeData nodeData, List originalElements) { - if (!nodeData.needsFactory()) { - // missing abstract methods only needs to be implemented - // if we need go generate factory for it. - return; - } - - List elements = new ArrayList<>(originalElements); - Set unusedElements = new HashSet<>(elements); - for (ExecutableElement method : nodeData.getAllTemplateMethods()) { - unusedElements.remove(method); - } - - for (NodeFieldData field : nodeData.getFields()) { - if (field.getGetter() != null) { - unusedElements.remove(field.getGetter()); - } - } - - for (NodeChildData child : nodeData.getChildren()) { - if (child.getAccessElement() != null) { - unusedElements.remove(child.getAccessElement()); - } - } - - for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) { - if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) { - nodeData.addError("The type %s must implement the inherited abstract method %s.", ElementUtils.getSimpleName(nodeData.getTemplateType()), - ElementUtils.getReadableSignature(unusedMethod)); - } - } - } - - private static void verifyNamingConvention(List methods, String prefix) { - for (int i = 0; i < methods.size(); i++) { - TemplateMethod m1 = methods.get(i); - if (m1.getMethodName().length() < 3 || !m1.getMethodName().startsWith(prefix)) { - m1.addError("Naming convention: method name must start with '%s'.", prefix); - } - } - } - - private static void verifySpecializationThrows(NodeData node) { - Map specializationMap = new HashMap<>(); - for (SpecializationData spec : node.getSpecializations()) { - specializationMap.put(spec.getMethodName(), spec); - } - for (SpecializationData sourceSpecialization : node.getSpecializations()) { - if (sourceSpecialization.getExceptions() != null) { - for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) { - for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) { - if (otherThrowsData != throwsData && ElementUtils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) { - throwsData.addError("Duplicate exception type."); - } - } - } - } - } - } - - private static void verifyConstructors(NodeData nodeData) { - List constructors = ElementFilter.constructorsIn(nodeData.getTemplateType().getEnclosedElements()); - if (constructors.isEmpty()) { - return; - } - - boolean oneNonPrivate = false; - for (ExecutableElement constructor : constructors) { - if (ElementUtils.getVisibility(constructor.getModifiers()) != Modifier.PRIVATE) { - oneNonPrivate = true; - break; - } - } - if (!oneNonPrivate && !nodeData.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) { - nodeData.addError("At least one constructor must be non-private."); - } - } - - private AnnotationMirror findFirstAnnotation(List elements, Class annotation) { - for (Element element : elements) { - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, element, annotation); - if (mirror != null) { - return mirror; - } - } - return null; - } - - private TypeMirror inheritType(AnnotationMirror annotation, String valueName, TypeMirror parentType) { - TypeMirror inhertNodeType = context.getTruffleTypes().getNode(); - TypeMirror value = ElementUtils.getAnnotationValue(TypeMirror.class, annotation, valueName); - if (ElementUtils.typeEquals(inhertNodeType, value)) { - return parentType; - } else { - return value; - } - } - - private ExecutableElement findGetter(List elements, String variableName, TypeMirror type) { - if (type == null) { - return null; - } - String methodName; - if (ElementUtils.typeEquals(type, context.getType(boolean.class))) { - methodName = "is" + ElementUtils.firstLetterUpperCase(variableName); - } else { - methodName = "get" + ElementUtils.firstLetterUpperCase(variableName); - } - - for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && ElementUtils.isAssignable(type, method.getReturnType())) { - return method; - } - } - return null; - } - - private static List collectSuperClasses(List collection, TypeElement element) { - if (element != null) { - collection.add(element); - if (element.getSuperclass() != null) { - collectSuperClasses(collection, ElementUtils.fromTypeMirror(element.getSuperclass())); - } - } - return collection; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -public class ShortCircuitParser extends NodeMethodParser { - - private final Set shortCircuitValues; - - public ShortCircuitParser(ProcessorContext context, NodeData node) { - super(context, node); - - shortCircuitValues = new HashSet<>(); - for (NodeExecutionData execution : node.getChildExecutions()) { - if (execution.isShortCircuit()) { - shortCircuitValues.add(execution.getIndexedName()); - } - } - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - String shortCircuitValue = ElementUtils.getAnnotationValue(String.class, mirror, "value"); - - return createDefaultMethodSpec(method, mirror, true, shortCircuitValue); - } - - @Override - protected ParameterSpec createReturnParameterSpec() { - return new ParameterSpec("has", getContext().getType(boolean.class)); - } - - @Override - public ShortCircuitData create(TemplateMethod method, boolean invalid) { - String shortCircuitValue = ElementUtils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value"); - - if (!shortCircuitValues.contains(shortCircuitValue)) { - method.addError("Invalid short circuit value %s.", shortCircuitValue); - } - - return new ShortCircuitData(method, shortCircuitValue); - } - - @Override - public Class getAnnotationType() { - return ShortCircuit.class; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/SpecializationGroup.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/SpecializationGroup.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.util.*; - -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature; - -/** - * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize - * and generic execute methods. - */ -public final class SpecializationGroup { - - private final List typeGuards; - private final List guards; - - private final NodeData node; - private final SpecializationData specialization; - private final List children = new ArrayList<>(); - - private SpecializationGroup parent; - - private SpecializationGroup(SpecializationData data) { - this.node = data.getNode(); - this.typeGuards = new ArrayList<>(); - this.guards = new ArrayList<>(); - this.specialization = data; - - TypeSignature sig = data.getTypeSignature(); - for (int i = 1; i < sig.size(); i++) { - typeGuards.add(new TypeGuard(sig.get(i), i - 1)); - } - this.guards.addAll(data.getGuards()); - } - - public SpecializationGroup(List children, List typeGuardsMatches, List guardMatches) { - assert !children.isEmpty() : "children must not be empty"; - this.typeGuards = typeGuardsMatches; - this.guards = guardMatches; - this.node = children.get(0).node; - this.specialization = null; - updateChildren(children); - } - - public List getAllGuards() { - List collectedGuards = new ArrayList<>(); - collectedGuards.addAll(typeGuards); - if (parent != null) { - collectedGuards.addAll(parent.getAllGuards()); - } - return collectedGuards; - } - - public List findElseConnectableGuards() { - if (!getTypeGuards().isEmpty()) { - return Collections.emptyList(); - } - - if (getGuards().isEmpty()) { - return Collections.emptyList(); - } - - List elseConnectableGuards = new ArrayList<>(); - int guardIndex = 0; - while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { - elseConnectableGuards.add(getGuards().get(guardIndex)); - guardIndex++; - } - - return elseConnectableGuards; - } - - private GuardExpression findNegatedGuardInPrevious(GuardExpression guard) { - SpecializationGroup previous = this.getPreviousGroup(); - if (previous == null) { - return null; - } - List elseConnectedGuards = previous.findElseConnectableGuards(); - - if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { - return null; - } - - /* Guard is else branch can be connected in previous specialization. */ - if (elseConnectedGuards.contains(guard)) { - return guard; - } - - GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size()); - if (guard.equalsNegated(previousGuard)) { - return guard; - } - return null; - } - - private void updateChildren(List childs) { - if (!children.isEmpty()) { - children.clear(); - } - this.children.addAll(childs); - for (SpecializationGroup child : childs) { - child.parent = this; - } - } - - public SpecializationGroup getParent() { - return parent; - } - - public List getTypeGuards() { - return typeGuards; - } - - public List getGuards() { - return guards; - } - - public List getChildren() { - return children; - } - - public SpecializationData getSpecialization() { - return specialization; - } - - private static SpecializationGroup combine(List groups) { - if (groups.isEmpty()) { - throw new IllegalArgumentException("empty combinations"); - } - if (groups.size() == 1) { - return null; - } - - List typeGuardsMatches = new ArrayList<>(); - List guardMatches = new ArrayList<>(); - - SpecializationGroup first = groups.get(0); - List others = groups.subList(1, groups.size()); - - outer: for (TypeGuard typeGuard : first.typeGuards) { - for (SpecializationGroup other : others) { - if (!other.typeGuards.contains(typeGuard)) { - // type guards can be combined unordered - continue outer; - } - } - typeGuardsMatches.add(typeGuard); - } - - outer: for (GuardExpression guard : first.guards) { - for (SpecializationGroup other : others) { - if (!other.guards.contains(guard)) { - // we must break here. One guard may depend on the other. - break outer; - } - } - guardMatches.add(guard); - } - - // check for guards for required type casts - for (Iterator iterator = guardMatches.iterator(); iterator.hasNext();) { - GuardExpression guardMatch = iterator.next(); - if (!guardMatch.getExpression().findBoundVariables().isEmpty()) { - iterator.remove(); - } - // TODO we need to be smarter here with bound parameters. - } - - if (typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) { - return null; - } - - for (SpecializationGroup group : groups) { - group.typeGuards.removeAll(typeGuardsMatches); - group.guards.removeAll(guardMatches); - } - - List newChildren = new ArrayList<>(groups); - return new SpecializationGroup(newChildren, typeGuardsMatches, guardMatches); - } - - public static SpecializationGroup create(SpecializationData specialization) { - return new SpecializationGroup(specialization); - } - - public static SpecializationGroup create(List specializations) { - List groups = new ArrayList<>(); - for (SpecializationData specialization : specializations) { - groups.add(new SpecializationGroup(specialization)); - } - return new SpecializationGroup(createCombinationalGroups(groups), Collections. emptyList(), Collections. emptyList()); - } - - @Override - public String toString() { - return "SpecializationGroup [typeGuards=" + typeGuards + ", guards=" + guards + "]"; - } - - private static List createCombinationalGroups(List groups) { - if (groups.size() <= 1) { - return groups; - } - List newGroups = new ArrayList<>(); - - int i = 0; - for (i = 0; i < groups.size();) { - SpecializationGroup combined = null; - for (int j = groups.size(); j > i + 1; j--) { - combined = combine(groups.subList(i, j)); - if (combined != null) { - break; - } - } - SpecializationGroup newGroup; - if (combined == null) { - newGroup = groups.get(i); - i++; - } else { - newGroup = combined; - List originalGroups = new ArrayList<>(combined.children); - combined.updateChildren(createCombinationalGroups(originalGroups)); - i += originalGroups.size(); - } - - newGroups.add(newGroup); - - } - - return newGroups; - } - - public SpecializationGroup getPreviousGroup() { - if (parent == null || parent.children.isEmpty()) { - return null; - } - int index = parent.children.indexOf(this); - if (index <= 0) { - return null; - } - return parent.children.get(index - 1); - } - - public int getUncheckedSpecializationIndex() { - int groupMaxIndex = getMaxSpecializationIndex(); - - int genericIndex = node.getSpecializations().indexOf(node.getGenericSpecialization()); - if (groupMaxIndex >= genericIndex) { - // no minimum state check for an generic index - groupMaxIndex = -1; - } - - if (groupMaxIndex > -1) { - // no minimum state check if already checked by parent group - int parentMaxIndex = -1; - if (getParent() != null) { - parentMaxIndex = getParent().getMaxSpecializationIndex(); - } - if (groupMaxIndex == parentMaxIndex) { - groupMaxIndex = -1; - } - } - return groupMaxIndex; - } - - public int getMaxSpecializationIndex() { - if (specialization != null) { - return specialization.getNode().getSpecializations().indexOf(specialization); - } else { - int max = Integer.MIN_VALUE; - for (SpecializationGroup childGroup : getChildren()) { - max = Math.max(max, childGroup.getMaxSpecializationIndex()); - } - return max; - } - } - - public static final class TypeGuard { - - private final int signatureIndex; - private final TypeMirror type; - - public TypeGuard(TypeMirror type, int signatureIndex) { - this.type = type; - this.signatureIndex = signatureIndex; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + signatureIndex; - result = prime * result + type.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } else if (obj == null) { - return false; - } else if (getClass() != obj.getClass()) { - return false; - } - - TypeGuard other = (TypeGuard) obj; - if (signatureIndex != other.signatureIndex) { - return false; - } else if (!type.equals(other.type)) { - return false; - } - return true; - } - - public int getSignatureIndex() { - return signatureIndex; - } - - public TypeMirror getType() { - return type; - } - } - - public SpecializationGroup getPrevious() { - if (getParent() == null) { - return null; - } - - List parentChildren = getParent().getChildren(); - int index = parentChildren.indexOf(this); - if (index <= 0) { - return null; - } - return parentChildren.get(index - 1); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/SpecializationMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/SpecializationMethodParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; -import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; - -public class SpecializationMethodParser extends NodeMethodParser { - - public SpecializationMethodParser(ProcessorContext context, NodeData operation) { - super(context, operation); - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - MethodSpec spec = createDefaultMethodSpec(method, mirror, true, null); - spec.getAnnotations().add(new AnnotatedParameterSpec(getContext().getDeclaredType(Cached.class))); - return spec; - } - - @Override - public SpecializationData create(TemplateMethod method, boolean invalid) { - return parseSpecialization(method); - } - - @Override - public Class getAnnotationType() { - return Specialization.class; - } - - private SpecializationData parseSpecialization(TemplateMethod method) { - List exceptionData = new ArrayList<>(); - if (method.getMethod() != null) { - AnnotationValue rewriteValue = ElementUtils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn"); - List exceptionTypes = ElementUtils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn"); - List rewriteOnTypes = new ArrayList<>(); - for (TypeMirror exceptionType : exceptionTypes) { - SpecializationThrowsData throwsData = new SpecializationThrowsData(method.getMarkerAnnotation(), rewriteValue, exceptionType); - if (!ElementUtils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) { - method.addError("A rewriteOn checked exception was specified but not thrown in the method's throws clause. The @%s method must specify a throws clause with the exception type '%s'.", - Specialization.class.getSimpleName(), ElementUtils.getQualifiedName(exceptionType)); - } - rewriteOnTypes.add(throwsData.getJavaClass()); - exceptionData.add(throwsData); - } - - for (TypeMirror typeMirror : method.getMethod().getThrownTypes()) { - if (!ElementUtils.canThrowType(rewriteOnTypes, typeMirror)) { - method.addError(rewriteValue, "A checked exception '%s' is thrown but is not specified using the rewriteOn property. " - + "Checked exceptions that are not used for rewriting are not handled by the DSL. Use RuntimeExceptions for this purpose instead.", - ElementUtils.getQualifiedName(typeMirror)); - } - } - - Collections.sort(exceptionData, new Comparator() { - - @Override - public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) { - return ElementUtils.compareByTypeHierarchy(o1.getJavaClass(), o2.getJavaClass()); - } - }); - } - SpecializationData specialization = new SpecializationData(getNode(), method, SpecializationKind.SPECIALIZED, exceptionData); - - if (method.getMethod() != null) { - String insertBeforeName = ElementUtils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "insertBefore"); - if (!insertBeforeName.equals("")) { - specialization.setInsertBeforeName(insertBeforeName); - } - - List containsDefs = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "contains"); - Set containsNames = specialization.getContainsNames(); - containsNames.clear(); - if (containsDefs != null) { - for (String include : containsDefs) { - if (!containsNames.contains(include)) { - specialization.getContainsNames().add(include); - } else { - AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); - specialization.addError(value, "Duplicate contains declaration '%s'.", include); - } - } - - } - } - - return specialization; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TemplateMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TemplateMethodParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +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.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -public abstract class TemplateMethodParser { - - protected final T template; - private final ProcessorContext context; - private final MethodSpecParser parser; - - private boolean parseNullOnError; - - public TemplateMethodParser(ProcessorContext context, T template) { - this.template = template; - this.context = context; - this.parser = new MethodSpecParser(template); - } - - public void setParseNullOnError(boolean parseNullOnError) { - this.parseNullOnError = parseNullOnError; - } - - public boolean isParseNullOnError() { - return parseNullOnError; - } - - public MethodSpecParser getParser() { - return parser; - } - - public ProcessorContext getContext() { - return context; - } - - public TypeSystemData getTypeSystem() { - return template.getTypeSystem(); - } - - public abstract MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror); - - public abstract E create(TemplateMethod method, boolean invalid); - - public abstract boolean isParsable(ExecutableElement method); - - public Class getAnnotationType() { - return null; - } - - public final List parse(List elements) { - List methods = new ArrayList<>(); - methods.addAll(ElementFilter.methodsIn(elements)); - - List parsedMethods = new ArrayList<>(); - boolean valid = true; - int naturalOrder = 0; - for (ExecutableElement method : methods) { - if (!isParsable(method)) { - continue; - } - - Class annotationType = getAnnotationType(); - AnnotationMirror mirror = null; - if (annotationType != null) { - mirror = ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType); - } - - E parsedMethod = parse(naturalOrder, method, mirror); - - if (method.getModifiers().contains(Modifier.PRIVATE) && parser.isEmitErrors()) { - parsedMethod.addError("Method annotated with @%s must not be private.", getAnnotationType().getSimpleName()); - parsedMethods.add(parsedMethod); - valid = false; - continue; - } - - if (parsedMethod != null) { - parsedMethods.add(parsedMethod); - } else { - valid = false; - } - naturalOrder++; - } - Collections.sort(parsedMethods); - - if (!valid && isParseNullOnError()) { - return null; - } - return parsedMethods; - } - - private E parse(int naturalOrder, ExecutableElement method, AnnotationMirror annotation) { - MethodSpec methodSpecification = createSpecification(method, annotation); - if (methodSpecification == null) { - return null; - } - - TemplateMethod templateMethod = parser.parse(methodSpecification, method, annotation, naturalOrder); - if (templateMethod != null) { - return create(templateMethod, templateMethod.hasErrors()); - } - return null; - } - - public final E create(String id, int naturalOrder, ExecutableElement methodMetadata, AnnotationMirror mirror, TypeMirror returnType, List parameterTypes) { - TemplateMethod method = parser.parseImpl(createSpecification(methodMetadata, mirror), naturalOrder, id, methodMetadata, mirror, returnType, parameterTypes); - if (method != null) { - return create(method, method.hasErrors()); - } - return null; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -class TypeCastParser extends TypeSystemMethodParser { - - public TypeCastParser(ProcessorContext context, TypeSystemData typeSystem) { - super(context, typeSystem); - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - TypeMirror targetTypeMirror = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "value"); - ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetTypeMirror); - returnTypeSpec.setAllowSubclasses(false); - MethodSpec spec = new MethodSpec(returnTypeSpec); - spec.addRequired(new ParameterSpec("value", getContext().getType(Object.class))); - return spec; - } - - @Override - public TypeCastData create(TemplateMethod method, boolean invalid) { - TypeMirror targetType = resolveCastOrCheck(method); - TypeMirror sourceType = getContext().getType(Object.class); - return new TypeCastData(method, sourceType, targetType); - } - - @Override - public Class getAnnotationType() { - return TypeCast.class; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.model.*; - -class TypeCheckParser extends TypeSystemMethodParser { - - public TypeCheckParser(ProcessorContext context, TypeSystemData typeSystem) { - super(context, typeSystem); - } - - @Override - public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { - MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", getContext().getType(boolean.class))); - spec.addRequired(new ParameterSpec("value", getContext().getType(Object.class))); - return spec; - } - - @Override - public TypeCheckData create(TemplateMethod method, boolean invalid) { - TypeMirror targetType = resolveCastOrCheck(method); - return new TypeCheckData(method, targetType, targetType); - } - - @Override - public Class getAnnotationType() { - return TypeCheck.class; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeSystemMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeSystemMethodParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -abstract class TypeSystemMethodParser extends TemplateMethodParser { - - public TypeSystemMethodParser(ProcessorContext context, TypeSystemData typeSystem) { - super(context, typeSystem); - } - - @Override - public final boolean isParsable(ExecutableElement method) { - return ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null; - } - - protected final TypeMirror resolveCastOrCheck(TemplateMethod method) { - Class annotationType = getAnnotationType(); - TypeMirror targetTypeMirror = ElementUtils.getAnnotationValue(TypeMirror.class, method.getMessageAnnotation(), "value"); - if (!method.getMethod().getModifiers().contains(Modifier.PUBLIC) || !method.getMethod().getModifiers().contains(Modifier.STATIC)) { - method.addError("@%s annotated method %s must be public and static.", annotationType.getSimpleName(), method.getMethodName()); - } - return targetTypeMirror; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeSystemParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeSystemParser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.parser; - -import java.lang.annotation.*; -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.dsl.processor.java.*; -import com.oracle.truffle.dsl.processor.model.*; - -@DSLOptions -public class TypeSystemParser extends AbstractParser { - - public static final List> ANNOTATIONS = Arrays.asList(TypeSystem.class); - - @Override - public Class getAnnotationType() { - return TypeSystem.class; - } - - @Override - protected TypeSystemData parse(Element element, AnnotationMirror mirror) { - TypeElement templateType = (TypeElement) element; - AnnotationMirror templateTypeAnnotation = mirror; - DSLOptions options = element.getAnnotation(DSLOptions.class); - if (options == null) { - options = TypeSystemParser.class.getAnnotation(DSLOptions.class); - } - assert options != null; - - TypeSystemData typeSystem = new TypeSystemData(context, templateType, templateTypeAnnotation, options, false); - - // annotation type on class path!? - TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName()); - if (annotationTypeElement == null) { - typeSystem.addError("Required class %s is not on the classpath.", getAnnotationType().getName()); - } - if (templateType.getModifiers().contains(Modifier.PRIVATE)) { - typeSystem.addError("A @%s must have at least package protected visibility.", getAnnotationType().getName()); - } - - if (templateType.getModifiers().contains(Modifier.FINAL)) { - typeSystem.addError("The @%s must not be final.", getAnnotationType().getName()); - } - if (typeSystem.hasErrors()) { - return typeSystem; - } - - if (typeSystem.hasErrors()) { - return typeSystem; - } - - verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class); - - List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType)); - List implicitCasts = new ImplicitCastParser(context, typeSystem).parse(elements); - List casts = new TypeCastParser(context, typeSystem).parse(elements); - List checks = new TypeCheckParser(context, typeSystem).parse(elements); - - if (casts == null || checks == null || implicitCasts == null) { - return typeSystem; - } - - List legacyTypes = ElementUtils.getAnnotationValueList(TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value"); - for (int i = 0; i < legacyTypes.size(); i++) { - legacyTypes.set(i, ElementUtils.fillInGenericWildcards(legacyTypes.get(i))); - } - - typeSystem.getLegacyTypes().addAll(legacyTypes); - verifyTypes(typeSystem); - typeSystem.getLegacyTypes().add(context.getType(Object.class)); - typeSystem.getLegacyTypes().add(context.getType(void.class)); - verifyNamesUnique(typeSystem); - - typeSystem.getImplicitCasts().addAll(implicitCasts); - typeSystem.getCasts().addAll(casts); - typeSystem.getChecks().addAll(checks); - - if (typeSystem.hasErrors()) { - return typeSystem; - } - return typeSystem; - } - - private void verifyExclusiveMethodAnnotation(Template template, Class... annotationTypes) { - List methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements()); - for (ExecutableElement method : methods) { - List foundAnnotations = new ArrayList<>(); - for (int i = 0; i < annotationTypes.length; i++) { - Class annotationType = annotationTypes[i]; - AnnotationMirror mirror = ElementUtils.findAnnotationMirror(context.getEnvironment(), method, annotationType); - if (mirror != null) { - foundAnnotations.add(mirror); - } - } - if (foundAnnotations.size() > 1) { - List annotationNames = new ArrayList<>(); - for (AnnotationMirror mirror : foundAnnotations) { - annotationNames.add("@" + ElementUtils.getSimpleName(mirror.getAnnotationType())); - } - - template.addError("Non exclusive usage of annotations %s.", annotationNames); - } - } - } - - private void verifyTypes(TypeSystemData typeSystem) { - for (TypeMirror type : typeSystem.getLegacyTypes()) { - if (isPrimitiveWrapper(type)) { - typeSystem.addError("Types must not contain primitive wrapper types."); - } - - if (ElementUtils.typeEquals(type, context.getType(Object.class))) { - typeSystem.addError("Types must not contain the generic type java.lang.Object."); - } - } - - verifyTypeOrder(typeSystem); - } - - private static void verifyTypeOrder(TypeSystemData typeSystem) { - Map> invalidTypes = new HashMap<>(); - - for (int i = typeSystem.getLegacyTypes().size() - 1; i >= 0; i--) { - TypeMirror typeData = typeSystem.getLegacyTypes().get(i); - TypeMirror type = typeSystem.boxType(typeData); - if (invalidTypes.containsKey(ElementUtils.getQualifiedName(type))) { - typeSystem.addError("Invalid type order. The type(s) %s are inherited from a earlier defined type %s.", invalidTypes.get(ElementUtils.getQualifiedName(type)), - ElementUtils.getQualifiedName(type)); - } - TypeElement element = ElementUtils.fromTypeMirror(type); - List nextInvalidTypes = new ArrayList<>(); - if (element != null) { - nextInvalidTypes.addAll(ElementUtils.getQualifiedSuperTypeNames(element)); - } - nextInvalidTypes.add(ElementUtils.getQualifiedName(type)); - - for (String qualifiedName : nextInvalidTypes) { - List inheritedTypes = invalidTypes.get(qualifiedName); - if (inheritedTypes == null) { - inheritedTypes = new ArrayList<>(); - invalidTypes.put(qualifiedName, inheritedTypes); - } - inheritedTypes.add(ElementUtils.getQualifiedName(typeSystem.boxType(typeData))); - } - } - } - - private boolean isPrimitiveWrapper(TypeMirror type) { - Types types = context.getEnvironment().getTypeUtils(); - for (TypeKind kind : TypeKind.values()) { - if (!kind.isPrimitive()) { - continue; - } - if (ElementUtils.typeEquals(type, types.boxedClass(types.getPrimitiveType(kind)).asType())) { - return true; - } - } - return false; - } - - private static void verifyNamesUnique(TypeSystemData typeSystem) { - Set usedNames = new HashSet<>(); - for (TypeMirror type : typeSystem.getLegacyTypes()) { - String boxedName = ElementUtils.getSimpleName(typeSystem.boxType(type)); - String primitiveName = ElementUtils.getSimpleName(type); - if (usedNames.contains(boxedName)) { - typeSystem.addError("Two types result in the same boxed name: %s.", boxedName); - } else if (usedNames.contains(primitiveName)) { - typeSystem.addError("Two types result in the same primitive name: %s.", primitiveName); - } - usedNames.add(boxedName); - usedNames.add(primitiveName); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Filterator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Filterator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.util; - -import java.util.*; - -public class Filterator implements Iterator { - - private final Predicate includePredicate; - private final Iterator elements; - - private boolean hasCached; - private T cached; - - public Filterator(Iterator elements, Predicate includePredicate) { - this.elements = elements; - this.includePredicate = includePredicate; - } - - public boolean hasNext() { - if (hasCached) { - return true; - } - nextValue(); - return hasCached; - } - - private void nextValue() { - while (!hasCached && elements.hasNext()) { - T element = elements.next(); - if (includePredicate.evaluate(element)) { - cached = element; - hasCached = true; - } - } - } - - public T next() { - T foundCached = getCached(); - if (foundCached != null) { - return foundCached; - } else { - nextValue(); - if (!hasCached) { - throw new NoSuchElementException(); - } - return getCached(); - } - } - - private T getCached() { - if (hasCached) { - hasCached = false; - T value = cached; - cached = null; - return value; - } - return null; - } - - @Override - public void remove() { - elements.remove(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/FilteredIterable.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/FilteredIterable.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.util; - -import java.util.*; - -public class FilteredIterable implements Iterable { - - private final Iterable delegate; - private final Predicate containedPredicate; - - public FilteredIterable(Iterable delegate, Predicate containedPredicate) { - this.delegate = delegate; - this.containedPredicate = containedPredicate; - } - - public Iterator iterator() { - return new Filterator<>(delegate.iterator(), containedPredicate); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Predicate.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Predicate.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.util; - -public interface Predicate { - - boolean evaluate(T value); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/verify/VerifyTruffleProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/verify/VerifyTruffleProcessor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +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.dsl.processor.verify; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static java.util.Collections.*; - -import java.io.*; -import java.util.*; - -import javax.annotation.processing.*; -import javax.lang.model.*; -import javax.lang.model.element.*; -import javax.tools.Diagnostic.Kind; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.dsl.processor.*; - -@SupportedAnnotationTypes({"com.oracle.truffle.api.CompilerDirectives.TruffleBoundary", "com.oracle.truffle.api.nodes.Node.Child"}) -public class VerifyTruffleProcessor extends AbstractProcessor { - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - /** - * Node class currently being processed. - */ - private Element scope; - - public static boolean isEnclosedIn(Element e, Element scopeElement) { - List elementHierarchy = getElementHierarchy(e); - return elementHierarchy.contains(scopeElement); - } - - void errorMessage(Element element, String format, Object... args) { - message(Kind.ERROR, element, format, args); - } - - void message(Kind kind, Element element, String format, Object... args) { - if (scope != null && !isEnclosedIn(element, scope)) { - // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=428357#c1 - List elementHierarchy = getElementHierarchy(element); - reverse(elementHierarchy); - - StringBuilder str = new StringBuilder(); - for (Element e : elementHierarchy) { - if (e.getKind() != ElementKind.PACKAGE) { - str.append(str.length() == 0 ? "" : "."); - str.append(e); - } - } - processingEnv.getMessager().printMessage(kind, String.format(str + ": " + format, args), scope); - } else { - processingEnv.getMessager().printMessage(kind, String.format(format, args), element); - } - } - - /** - * Bugs in an annotation processor can cause silent failure so try to report any exception - * throws as errors. - */ - private void reportException(Kind kind, Element element, Throwable t) { - StringWriter buf = new StringWriter(); - t.printStackTrace(new PrintWriter(buf)); - buf.toString(); - message(kind, element, "Exception thrown during processing: %s", buf.toString()); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - if (roundEnv.processingOver()) { - return false; - } - - TypeElement virtualFrameType = processingEnv.getElementUtils().getTypeElement("com.oracle.truffle.api.frame.VirtualFrame"); - - for (Element element : roundEnv.getElementsAnnotatedWith(TruffleBoundary.class)) { - scope = element; - try { - ExecutableElement method = (ExecutableElement) element; - - for (VariableElement parameter : method.getParameters()) { - Element paramType = processingEnv.getTypeUtils().asElement(parameter.asType()); - if (paramType != null && paramType.equals(virtualFrameType)) { - errorMessage(element, "Method %s cannot be annotated with @%s and have a parameter of type %s", method.getSimpleName(), TruffleBoundary.class.getSimpleName(), - paramType.getSimpleName()); - } - } - } catch (Throwable t) { - reportException(isBug367599(t) ? Kind.NOTE : Kind.ERROR, element, t); - } finally { - scope = null; - } - } - - for (Element e : roundEnv.getElementsAnnotatedWith(Child.class)) { - if (e.getModifiers().contains(Modifier.FINAL)) { - emitError("@Child field cannot be final", e); - continue; - } - assertNoErrorExpected(e); - } - return false; - } - - void assertNoErrorExpected(Element element) { - ExpectError.assertNoErrorExpected(processingEnv, element); - } - - void emitError(String message, Element element) { - if (ExpectError.isExpectedError(processingEnv, element, message)) { - return; - } - processingEnv.getMessager().printMessage(Kind.ERROR, message, element); - } - - /** - * Determines if a given exception is (most likely) caused by Bug 367599. - */ - public static boolean isBug367599(Throwable t) { - if (t instanceof FilerException) { - for (StackTraceElement ste : t.getStackTrace()) { - if (ste.toString().contains("org.eclipse.jdt.internal.apt.pluggable.core.filer.IdeFilerImpl.create")) { - // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=367599 - return true; - } - } - } - if (t.getCause() != null) { - return isBug367599(t.getCause()); - } - return false; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/META-INF/services/com.oracle.truffle.api.object.LayoutFactory --- a/graal/com.oracle.truffle.object.basic/src/META-INF/services/com.oracle.truffle.api.object.LayoutFactory Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.truffle.object.basic.DefaultLayoutFactory diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicAllocator.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicAllocator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2012, 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.object.basic; - -import static com.oracle.truffle.object.basic.BasicLocations.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.LocationImpl.InternalLongLocation; -import com.oracle.truffle.object.Locations.ConstantLocation; -import com.oracle.truffle.object.Locations.DeclaredDualLocation; -import com.oracle.truffle.object.Locations.DualLocation; -import com.oracle.truffle.object.Locations.ValueLocation; -import com.oracle.truffle.object.basic.BasicLocations.BooleanLocationDecorator; -import com.oracle.truffle.object.basic.BasicLocations.DoubleLocationDecorator; -import com.oracle.truffle.object.basic.BasicLocations.IntLocationDecorator; -import com.oracle.truffle.object.basic.BasicLocations.LongArrayLocation; -import com.oracle.truffle.object.basic.BasicLocations.LongFieldLocation; -import com.oracle.truffle.object.basic.BasicLocations.ObjectArrayLocation; - -public abstract class BasicAllocator extends ShapeImpl.BaseAllocator { - - public BasicAllocator(LayoutImpl layout) { - super(layout); - advance(((BasicLayout) layout).getPrimitiveArrayLocation()); - } - - public BasicAllocator(ShapeImpl shape) { - super(shape); - } - - private BasicLayout getLayout() { - return (BasicLayout) layout; - } - - @Override - protected Location moveLocation(Location oldLocation) { - if (oldLocation instanceof DeclaredDualLocation) { - return advance(newDeclaredDualLocation(((DeclaredDualLocation) oldLocation).get(null, false))); - } else if (oldLocation instanceof DualLocation) { - return advance(newDualLocation(((DualLocation) oldLocation).getType())); - } else if (oldLocation instanceof LongLocation) { - return newLongLocation(oldLocation.isFinal()); - } else if (oldLocation instanceof IntLocation) { - return newIntLocation(oldLocation.isFinal()); - } else if (oldLocation instanceof DoubleLocation) { - return newDoubleLocation(oldLocation.isFinal()); - } else if (oldLocation instanceof BooleanLocation) { - return newBooleanLocation(oldLocation.isFinal()); - } else if (oldLocation instanceof ObjectLocation) { - return newObjectLocation(oldLocation.isFinal(), ((ObjectLocation) oldLocation).isNonNull()); - } else { - assert oldLocation instanceof ValueLocation; - return advance(oldLocation); - } - } - - @Override - public Location newObjectLocation(boolean useFinal, boolean nonNull) { - if (ObjectStorageOptions.InObjectFields) { - int insertPos = objectFieldSize; - while (insertPos + OBJECT_SIZE <= getLayout().getObjectFieldCount()) { - return advance((Location) getLayout().getObjectFieldLocation(insertPos)); - } - } - return newObjectArrayLocation(useFinal, nonNull); - } - - @SuppressWarnings("unused") - private Location newObjectArrayLocation(boolean useFinal, boolean nonNull) { - return advance(new ObjectArrayLocation(objectArraySize, getLayout().getObjectArrayLocation())); - } - - @Override - public Location newTypedObjectLocation(boolean useFinal, Class type, boolean nonNull) { - return newObjectLocation(useFinal, nonNull); - } - - @Override - public Location newIntLocation(boolean useFinal) { - if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.IntegerLocations) { - if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { - return advance(new IntLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize))); - } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { - return advance(new IntLocationDecorator(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation()))); - } - } - return newObjectLocation(useFinal, true); - } - - @Override - public Location newDoubleLocation(boolean useFinal) { - if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.DoubleLocations) { - if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { - return advance(new DoubleLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize), getLayout().isAllowedIntToDouble())); - } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { - return advance(new DoubleLocationDecorator(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation()), getLayout().isAllowedIntToDouble())); - } - } - return newObjectLocation(useFinal, true); - } - - @Override - public Location newLongLocation(boolean useFinal) { - if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.LongLocations) { - if (ObjectStorageOptions.InObjectFields && primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { - return advance((Location) LongFieldLocation.create(getLayout().getPrimitiveFieldLocation(primitiveFieldSize), getLayout().isAllowedIntToLong())); - } else if (getLayout().hasPrimitiveExtensionArray() && isPrimitiveExtensionArrayAvailable()) { - return advance(new LongArrayLocation(primitiveArraySize, getLayout().getPrimitiveArrayLocation(), getLayout().isAllowedIntToLong())); - } - } - return newObjectLocation(useFinal, true); - } - - @Override - public Location newBooleanLocation(boolean useFinal) { - if (ObjectStorageOptions.PrimitiveLocations && ObjectStorageOptions.BooleanLocations) { - if (primitiveFieldSize + LONG_SIZE <= getLayout().getPrimitiveFieldCount()) { - return advance(new BooleanLocationDecorator(getLayout().getPrimitiveFieldLocation(primitiveFieldSize))); - } - } - return newObjectLocation(useFinal, true); - } - - private boolean isPrimitiveExtensionArrayAvailable() { - return hasPrimitiveArray; - } - - @Override - protected Location locationForValueUpcast(Object value, Location oldLocation) { - assert !(value instanceof Class); - if (oldLocation instanceof DualLocation) { - DualLocation dualLocation = (DualLocation) oldLocation; - if (dualLocation.getType() == null) { - if (value instanceof Integer) { - return dualLocation.changeType(int.class); - } else if (value instanceof Double) { - return dualLocation.changeType(double.class); - } else if (value instanceof Long) { - return dualLocation.changeType(long.class); - } else if (value instanceof Boolean) { - return dualLocation.changeType(boolean.class); - } else { - return dualLocation.changeType(Object.class); - } - } else if (dualLocation.getType().isPrimitive()) { - return dualLocation.changeType(Object.class); - } else { - throw new UnsupportedOperationException(); - } - } else if (oldLocation instanceof ConstantLocation) { - return constantLocation(value); - } else { - throw new UnsupportedOperationException(); - } - } - - @Override - protected DeclaredDualLocation newDeclaredDualLocation(Object value) { - return new DeclaredDualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), value, layout); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLayout.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLayout.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2012, 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.object.basic; - -import java.util.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.api.object.Shape.Allocator; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.LocationImpl.InternalLongLocation; -import com.oracle.truffle.object.Locations.DualLocation; -import com.oracle.truffle.object.basic.BasicLocations.ObjectFieldLocation; -import com.oracle.truffle.object.basic.BasicLocations.SimpleObjectFieldLocation; - -public class BasicLayout extends LayoutImpl { - private final ObjectLocation[] objectFields; - private final InternalLongLocation[] primitiveFields; - private final Location objectArrayLocation; - private final Location primitiveArrayLocation; - - BasicLayout(EnumSet allowedImplicitCasts, LayoutStrategy strategy) { - super(allowedImplicitCasts, DynamicObjectBasic.class, strategy); - this.objectFields = DynamicObjectBasic.OBJECT_FIELD_LOCATIONS; - this.primitiveFields = DynamicObjectBasic.PRIMITIVE_FIELD_LOCATIONS; - this.primitiveArrayLocation = DynamicObjectBasic.PRIMITIVE_ARRAY_LOCATION; - this.objectArrayLocation = DynamicObjectBasic.OBJECT_ARRAY_LOCATION; - } - - static LayoutImpl createLayoutImpl(EnumSet allowedImplicitCasts, LayoutStrategy strategy) { - return new BasicLayout(allowedImplicitCasts, strategy); - } - - @Override - public DynamicObject newInstance(Shape shape) { - return new DynamicObjectBasic(shape); - } - - @Override - public Shape createShape(ObjectType operations, Object sharedData, int id) { - return new ShapeBasic(this, sharedData, operations, id); - } - - @Override - protected boolean hasObjectExtensionArray() { - return true; - } - - @Override - protected boolean hasPrimitiveExtensionArray() { - return true; - } - - @Override - protected int getObjectFieldCount() { - return objectFields.length; - } - - @Override - protected int getPrimitiveFieldCount() { - return primitiveFields.length; - } - - @Override - protected Location getObjectArrayLocation() { - return objectArrayLocation; - } - - @Override - protected Location getPrimitiveArrayLocation() { - return primitiveArrayLocation; - } - - protected ObjectLocation getObjectFieldLocation(int index) { - return objectFields[index]; - } - - protected InternalLongLocation getPrimitiveFieldLocation(int index) { - return primitiveFields[index]; - } - - @Override - public Allocator createAllocator() { - LayoutImpl layout = this; - Allocator allocator = getStrategy().createAllocator(layout); - return allocator; - } - - @Override - protected int objectFieldIndex(Location location) { - if (location instanceof DualLocation) { - return objectFieldIndex((Location) ((DualLocation) location).getObjectLocation()); - } else if (location instanceof ObjectFieldLocation) { - return ((ObjectFieldLocation) location).getIndex(); - } else if (location instanceof SimpleObjectFieldLocation) { - return ((SimpleObjectFieldLocation) location).getIndex(); - } else { - return 0; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLocations.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLocations.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,717 +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.object.basic; - -import java.lang.invoke.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.LocationImpl.InternalLongLocation; - -/** - * Property location. - * - * @see Shape - * @see Property - * @see DynamicObject - */ -public abstract class BasicLocations { - static final int LONG_SIZE = 1; - static final int OBJECT_SIZE = 1; - - public abstract static class ArrayLocation extends LocationImpl { - protected final int index; - protected final Location arrayLocation; - - public ArrayLocation(int index, Location arrayLocation) { - this.index = index; - this.arrayLocation = arrayLocation; - } - - protected final Object getArray(DynamicObject store, boolean condition) { - // non-null cast - return arrayLocation.get(store, condition); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + index; - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - ArrayLocation other = (ArrayLocation) obj; - if (index != other.index) { - return false; - } - return true; - } - - public final int getIndex() { - return index; - } - - @Override - protected String getWhereString() { - return "[" + index + "]"; - } - } - - public abstract static class FieldLocation extends LocationImpl { - private final int index; - - public FieldLocation(int index) { - this.index = index; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + index; - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - FieldLocation other = (FieldLocation) obj; - if (index != other.index) { - return false; - } - return true; - } - - public final int getIndex() { - return index; - } - - @Override - protected String getWhereString() { - return "@" + index; - } - } - - public abstract static class MethodHandleFieldLocation extends FieldLocation { - protected final MethodHandle getter; - protected final MethodHandle setter; - - public MethodHandleFieldLocation(int index, MethodHandle getter, MethodHandle setter) { - super(index); - this.getter = getter; - this.setter = setter; - } - } - - public static class ObjectArrayLocation extends ArrayLocation implements ObjectLocation { - public ObjectArrayLocation(int index, Location arrayLocation) { - super(index, arrayLocation); - } - - @Override - public Object get(DynamicObject store, boolean condition) { - return ((Object[]) getArray(store, condition))[index]; - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - ((Object[]) getArray(store, false))[index] = value; - } - - @Override - public boolean canStore(Object value) { - return true; - } - - public Class getType() { - return Object.class; - } - - public final boolean isNonNull() { - return false; - } - - @Override - public int objectArrayCount() { - return OBJECT_SIZE; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitObjectArray(index, OBJECT_SIZE); - } - } - - public static class ObjectFieldLocation extends MethodHandleFieldLocation implements ObjectLocation { - - public ObjectFieldLocation(int index, MethodHandle getter, MethodHandle setter) { - super(index, getter, setter); - } - - @Override - public Object get(DynamicObject store, boolean condition) { - try { - return getter.invokeExact(store); - } catch (Throwable e) { - CompilerDirectives.transferToInterpreter(); - throw new IllegalStateException(e); - } - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - try { - setter.invokeExact(store, value); - } catch (Throwable e) { - CompilerDirectives.transferToInterpreter(); - throw new IllegalStateException(e); - } - } - - @Override - public boolean canStore(Object value) { - return true; - } - - public Class getType() { - return Object.class; - } - - public boolean isNonNull() { - return false; - } - - @Override - public int objectFieldCount() { - return OBJECT_SIZE; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitObjectField(getIndex(), OBJECT_SIZE); - } - } - - public abstract static class SimpleObjectFieldLocation extends FieldLocation implements ObjectLocation { - - public SimpleObjectFieldLocation(int index) { - super(index); - } - - @Override - public abstract Object get(DynamicObject store, boolean condition); - - @Override - public abstract void setInternal(DynamicObject store, Object value); - - @Override - public boolean canStore(Object value) { - return true; - } - - public Class getType() { - return Object.class; - } - - public boolean isNonNull() { - return false; - } - - @Override - public int objectFieldCount() { - return OBJECT_SIZE; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitObjectField(getIndex(), OBJECT_SIZE); - } - } - - public static class LongArrayLocation extends ArrayLocation implements InternalLongLocation { - protected final boolean allowInt; - - public LongArrayLocation(int index, Location arrayLocation, boolean allowInt) { - super(index, arrayLocation); - this.allowInt = allowInt; - } - - public LongArrayLocation(int index, Location arrayLocation) { - this(index, arrayLocation, false); - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getLong(store, condition); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setLongInternal(store, ((Number) value).longValue()); - } else { - throw incompatibleLocation(); - } - } - - @Override - public long getLong(DynamicObject store, boolean condition) { - return ((long[]) getArray(store, condition))[index]; - } - - public final void setLongInternal(DynamicObject store, long value) { - ((long[]) getArray(store, false))[index] = value; - } - - @Override - public void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException { - setLongInternal(store, value); - } - - @Override - public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setLongInternal(store, value); - } - - @Override - public final void setLong(DynamicObject store, long value) throws FinalLocationException { - setLong(store, value, null); - } - - public final long getLong(DynamicObject store, Shape shape) { - return getLong(store, checkShape(store, shape)); - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Long || (allowInt && value instanceof Integer); - } - - public final Class getType() { - return long.class; - } - - @Override - public int primitiveArrayCount() { - return LONG_SIZE; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitPrimitiveArray(getIndex(), LONG_SIZE); - } - } - - public static class LongFieldLocation extends MethodHandleFieldLocation implements InternalLongLocation { - public LongFieldLocation(int index, MethodHandle getter, MethodHandle setter) { - super(index, getter, setter); - } - - public static LongLocation create(InternalLongLocation longLocation, boolean allowInt) { - if ((!allowInt && (longLocation instanceof LongLocationDecorator)) || (longLocation instanceof LongLocationDecorator && ((LongLocationDecorator) longLocation).allowInt == allowInt)) { - return longLocation; - } else { - return new LongLocationDecorator(longLocation, allowInt); - } - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getLong(store, condition); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setLongInternal(store, (long) value); - } else { - throw incompatibleLocation(); - } - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Long; - } - - @Override - public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setLongInternal(store, value); - } - - public long getLong(DynamicObject store, boolean condition) { - try { - return (long) getter.invokeExact(store); - } catch (Throwable e) { - CompilerDirectives.transferToInterpreter(); - throw new IllegalStateException(e); - } - } - - public void setLong(DynamicObject store, long value, Shape shape) { - setLongInternal(store, value); - } - - public final void setLong(DynamicObject store, long value) throws FinalLocationException { - setLong(store, value, null); - } - - public final void setLongInternal(DynamicObject store, long value) { - try { - setter.invokeExact(store, value); - } catch (Throwable e) { - CompilerDirectives.transferToInterpreter(); - throw new IllegalStateException(e); - } - } - - public final long getLong(DynamicObject store, Shape shape) { - return getLong(store, checkShape(store, shape)); - } - - @Override - public final int primitiveFieldCount() { - return LONG_SIZE; - } - - public final Class getType() { - return long.class; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitPrimitiveField(getIndex(), LONG_SIZE); - } - } - - public static class LongLocationDecorator extends PrimitiveLocationDecorator implements InternalLongLocation { - protected final boolean allowInt; - - public LongLocationDecorator(InternalLongLocation longLocation, boolean allowInt) { - super(longLocation); - this.allowInt = allowInt; - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getLong(store, condition); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setLongInternal(store, ((Number) value).longValue()); - } else { - throw incompatibleLocation(); - } - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Long || (allowInt && value instanceof Integer); - } - - @Override - public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setLongInternal(store, value); - } - - public Class getType() { - return long.class; - } - } - - public abstract static class SimpleLongFieldLocation extends FieldLocation implements InternalLongLocation { - - public SimpleLongFieldLocation(int index) { - super(index); - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getLong(store, condition); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setLongInternal(store, ((Number) value).longValue()); - } else { - throw incompatibleLocation(); - } - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Long; - } - - @Override - public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setLongInternal(store, value); - } - - public abstract long getLong(DynamicObject store, boolean condition); - - public final long getLong(DynamicObject store, Shape shape) { - return getLong(store, checkShape(store, shape)); - } - - public final void setLong(DynamicObject store, long value) { - setLong(store, value, null); - } - - public void setLong(DynamicObject store, long value, Shape shape) { - setLongInternal(store, value); - } - - public abstract void setLongInternal(DynamicObject store, long value); - - @Override - public final int primitiveFieldCount() { - return LONG_SIZE; - } - - public final Class getType() { - return long.class; - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - locationVisitor.visitPrimitiveField(getIndex(), LONG_SIZE); - } - } - - public abstract static class PrimitiveLocationDecorator extends LocationImpl { - private final InternalLongLocation longLocation; - - public PrimitiveLocationDecorator(InternalLongLocation longLocation) { - this.longLocation = longLocation; - } - - public final long getLong(DynamicObject store, Shape shape) { - return longLocation.getLong(store, shape); - } - - public final long getLong(DynamicObject store, boolean condition) { - return longLocation.getLong(store, condition); - } - - public final void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException { - longLocation.setLong(store, value, shape); - } - - public final void setLong(DynamicObject store, long value) throws FinalLocationException { - longLocation.setLong(store, value); - } - - public final void setLongInternal(DynamicObject store, long value) { - longLocation.setLongInternal(store, value); - } - - @Override - public final int primitiveFieldCount() { - return ((LocationImpl) longLocation).primitiveFieldCount(); - } - - @Override - public final int primitiveArrayCount() { - return ((LocationImpl) longLocation).primitiveArrayCount(); - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - ((LocationImpl) longLocation).accept(locationVisitor); - } - } - - public static class IntLocationDecorator extends PrimitiveLocationDecorator implements IntLocation { - public IntLocationDecorator(InternalLongLocation longLocation) { - super(longLocation); - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getInt(store, condition); - } - - public int getInt(DynamicObject store, boolean condition) { - return (int) getLong(store, condition); - } - - public void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException { - setLong(store, value, shape); - } - - @Override - public final void setInt(DynamicObject store, int value) throws FinalLocationException { - setInt(store, value, null); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setLongInternal(store, (int) value); - } else { - throw incompatibleLocation(); - } - } - - public final int getInt(DynamicObject store, Shape shape) { - return getInt(store, checkShape(store, shape)); - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Integer; - } - - @Override - public final void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setLongInternal(store, value); - } - - public Class getType() { - return int.class; - } - } - - public static class DoubleLocationDecorator extends PrimitiveLocationDecorator implements DoubleLocation { - private final boolean allowInt; - - public DoubleLocationDecorator(InternalLongLocation longLocation, boolean allowInt) { - super(longLocation); - this.allowInt = allowInt; - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getDouble(store, condition); - } - - public double getDouble(DynamicObject store, boolean condition) { - return Double.longBitsToDouble(getLong(store, condition)); - } - - public void setDouble(DynamicObject store, double value, Shape shape) { - setLongInternal(store, Double.doubleToRawLongBits(value)); - } - - public void setDouble(DynamicObject store, double value) { - setDouble(store, value, null); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setDouble(store, ((Number) value).doubleValue(), null); - } else { - throw incompatibleLocation(); - } - } - - public final double getDouble(DynamicObject store, Shape shape) { - return getDouble(store, checkShape(store, shape)); - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Double || (allowInt && value instanceof Integer); - } - - @Override - public final void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setDouble(store, value, newShape); - } - - public Class getType() { - return double.class; - } - } - - public static class BooleanLocationDecorator extends PrimitiveLocationDecorator implements BooleanLocation { - public BooleanLocationDecorator(InternalLongLocation longLocation) { - super(longLocation); - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getBoolean(store, condition); - } - - public boolean getBoolean(DynamicObject store, boolean condition) { - return getLong(store, condition) != 0; - } - - public void setBoolean(DynamicObject store, boolean value, Shape shape) { - setLongInternal(store, value ? 1 : 0); - } - - public void setBoolean(DynamicObject store, boolean value) { - setBoolean(store, value, null); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (canStore(value)) { - setBoolean(store, (boolean) value, null); - } else { - throw incompatibleLocation(); - } - } - - public final boolean getBoolean(DynamicObject store, Shape shape) { - return getBoolean(store, checkShape(store, shape)); - } - - @Override - public final boolean canStore(Object value) { - return value instanceof Boolean; - } - - @Override - public final void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape) { - store.setShapeAndGrow(oldShape, newShape); - setBoolean(store, value, newShape); - } - - public Class getType() { - return boolean.class; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DefaultLayoutFactory.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DefaultLayoutFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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.object.basic; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; - -public class DefaultLayoutFactory implements LayoutFactory { - public Layout createLayout(LayoutBuilder layoutBuilder) { - return BasicLayout.createLayoutImpl(layoutBuilder.getAllowedImplicitCasts(), new DefaultStrategy()); - } - - public Property createProperty(Object id, Location location) { - return createProperty(id, location, 0); - } - - public Property createProperty(Object id, Location location, int flags) { - return new PropertyImpl(id, location, flags); - } - - public int getPriority() { - return 10; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DefaultStrategy.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DefaultStrategy.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +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.object.basic; - -import java.util.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.ShapeImpl.BaseAllocator; - -class DefaultStrategy implements LayoutStrategy { - public boolean updateShape(DynamicObject object) { - assert object.getShape().isValid(); - return false; - } - - public Shape returnCached(Shape newShape) { - assert newShape.isValid(); - return newShape; - } - - private static boolean assertLocationInRange(Shape shape, Location location) { - BasicLayout layout = (BasicLayout) shape.getLayout(); - assert (shape.getPrimitiveFieldSize() + ((LocationImpl) location).primitiveFieldCount() <= layout.getPrimitiveFieldCount()); - assert (shape.getObjectFieldSize() + ((LocationImpl) location).objectFieldCount() <= layout.getObjectFieldCount()); - return true; - } - - public Shape ensureSpace(Shape shape, Location location) { - Objects.requireNonNull(location); - assert assertLocationInRange(shape, location); - return shape; - } - - public boolean isAutoExtArray() { - return false; - } - - public Property generalizeProperty(DynamicObject object, Property oldProperty, Object value) { - Shape oldShape = object.getShape(); - Location oldLocation = oldProperty.getLocation(); - Location newLocation = ((BasicAllocator) oldShape.allocator()).locationForValueUpcast(value, oldLocation); - Property newProperty = oldProperty.relocate(newLocation); - Shape newShape = oldShape.replaceProperty(oldProperty, newProperty); - newProperty.setSafe(object, value, oldShape, newShape); - return newProperty; - } - - public Property generalizeProperty(DynamicObject object, Property oldProperty, Object value, Shape currentShape, Shape oldNewShape) { - Location oldLocation = oldProperty.getLocation(); - Location newLocation = ((BasicAllocator) currentShape.allocator()).locationForValueUpcast(value, oldLocation); - Property newProperty = oldProperty.relocate(newLocation); - Shape newShape = oldNewShape.replaceProperty(oldProperty, newProperty); - newProperty.setSafe(object, value, currentShape, newShape); - return newProperty; - } - - public BaseAllocator createAllocator(Shape shape) { - return new DefaultAllocatorImpl((ShapeImpl) shape); - } - - public BaseAllocator createAllocator(Layout layout) { - return new DefaultAllocatorImpl((LayoutImpl) layout); - } - - public static class DefaultAllocatorImpl extends BasicAllocator { - protected DefaultAllocatorImpl(LayoutImpl layout) { - super(layout); - } - - protected DefaultAllocatorImpl(ShapeImpl shape) { - super(shape); - } - - @Override - public Location locationForValue(Object value, boolean useFinal, boolean nonNull) { - return super.newDualLocationForValue(value); - } - - @Override - public Location declaredLocation(Object value) { - return super.newDeclaredDualLocation(value); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DynamicObjectBasic.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/DynamicObjectBasic.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +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.object.basic; - -import java.lang.annotation.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.basic.BasicLocations.SimpleLongFieldLocation; -import com.oracle.truffle.object.basic.BasicLocations.SimpleObjectFieldLocation; - -public class DynamicObjectBasic extends DynamicObjectImpl { - @Retention(RetentionPolicy.RUNTIME) - protected @interface DynamicField { - } - - @DynamicField private long primitive1; - @DynamicField private long primitive2; - @DynamicField private long primitive3; - @DynamicField private Object object1; - @DynamicField private Object object2; - @DynamicField private Object object3; - @DynamicField private Object object4; - private Object[] objext; - private long[] primext; - - public DynamicObjectBasic(Shape shape) { - super(shape); - } - - @Override - protected final void initialize(Shape shape) { - assert getObjectStore(shape) == null; - int capacity = ((ShapeImpl) shape).getObjectArrayCapacity(); - if (capacity != 0) { - this.setObjectStore(new Object[capacity], shape); - } - if (((ShapeImpl) shape).getPrimitiveArrayCapacity() != 0) { - this.setPrimitiveStore(new long[((ShapeImpl) shape).getPrimitiveArrayCapacity()], shape); - } - } - - /** - * Simpler version of {@link #resizeObjectStore} when the object is only increasing in size. - */ - @Override - protected final void growObjectStore(Shape oldShape, Shape newShape) { - int oldObjectArrayCapacity = ((ShapeImpl) oldShape).getObjectArrayCapacity(); - int newObjectArrayCapacity = ((ShapeImpl) newShape).getObjectArrayCapacity(); - if (oldObjectArrayCapacity != newObjectArrayCapacity) { - growObjectStoreIntl(oldObjectArrayCapacity, newObjectArrayCapacity, oldShape); - } - } - - private void growObjectStoreIntl(int oldObjectArrayCapacity, int newObjectArrayCapacity, Shape newShape) { - Object[] newObjectStore = new Object[newObjectArrayCapacity]; - if (oldObjectArrayCapacity != 0) { - // monotonic growth assumption - assert oldObjectArrayCapacity < newObjectArrayCapacity; - Object[] oldObjectStore = this.getObjectStore(newShape); - for (int i = 0; i < oldObjectArrayCapacity; ++i) { - newObjectStore[i] = oldObjectStore[i]; - } - } - this.setObjectStore(newObjectStore, newShape); - } - - /** - * Simpler version of {@link #resizePrimitiveStore} when the object is only increasing in size. - */ - @Override - protected final void growPrimitiveStore(Shape oldShape, Shape newShape) { - assert ((ShapeImpl) newShape).hasPrimitiveArray(); - int oldPrimitiveCapacity = oldShape.getPrimitiveArrayCapacity(); - int newPrimitiveCapacity = newShape.getPrimitiveArrayCapacity(); - if (newPrimitiveCapacity == 0) { - // due to obsolescence, we might have to reserve an empty primitive array slot - this.setPrimitiveStore(null, newShape); - } else if (oldPrimitiveCapacity != newPrimitiveCapacity) { - growPrimitiveStoreIntl(oldPrimitiveCapacity, newPrimitiveCapacity, oldShape); - } - } - - private void growPrimitiveStoreIntl(int oldPrimitiveCapacity, int newPrimitiveCapacity, Shape newShape) { - long[] newPrimitiveArray = new long[newPrimitiveCapacity]; - if (oldPrimitiveCapacity != 0) { - // primitive array can shrink due to type changes - long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); - for (int i = 0; i < Math.min(oldPrimitiveCapacity, newPrimitiveCapacity); ++i) { - newPrimitiveArray[i] = oldPrimitiveArray[i]; - } - } - this.setPrimitiveStore(newPrimitiveArray, newShape); - } - - @Override - protected final void resizeObjectStore(Shape oldShape, Shape newShape) { - Object[] newObjectStore = null; - int destinationCapacity = newShape.getObjectArrayCapacity(); - if (destinationCapacity != 0) { - newObjectStore = new Object[destinationCapacity]; - int sourceCapacity = oldShape.getObjectArrayCapacity(); - if (sourceCapacity != 0) { - Object[] oldObjectStore = getObjectStore(newShape); - for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { - newObjectStore[i] = oldObjectStore[i]; - } - } - } - this.setObjectStore(newObjectStore, newShape); - } - - private Object[] getObjectStore(@SuppressWarnings("unused") Shape currentShape) { - return objext; - } - - private void setObjectStore(Object[] newArray, @SuppressWarnings("unused") Shape currentShape) { - objext = newArray; - } - - private long[] getPrimitiveStore(@SuppressWarnings("unused") Shape currentShape) { - return primext; - } - - private void setPrimitiveStore(long[] newArray, @SuppressWarnings("unused") Shape currentShape) { - primext = newArray; - } - - @Override - protected final void resizePrimitiveStore(Shape oldShape, Shape newShape) { - assert newShape.hasPrimitiveArray(); - long[] newPrimitiveArray = null; - int destinationCapacity = newShape.getPrimitiveArrayCapacity(); - if (destinationCapacity != 0) { - newPrimitiveArray = new long[destinationCapacity]; - int sourceCapacity = oldShape.getPrimitiveArrayCapacity(); - if (sourceCapacity != 0) { - long[] oldPrimitiveArray = this.getPrimitiveStore(newShape); - for (int i = 0; i < Math.min(sourceCapacity, destinationCapacity); ++i) { - newPrimitiveArray[i] = oldPrimitiveArray[i]; - } - } - } - this.setPrimitiveStore(newPrimitiveArray, newShape); - } - - /** - * Check whether fast transition is valid. - * - * @see #setShapeAndGrow - */ - @SuppressWarnings("unused") - private boolean checkSetShape(Shape oldShape, Shape newShape) { - Shape currentShape = getShape(); - assert oldShape != newShape : "Wrong old shape assumption?"; - assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; - assert oldShape == currentShape || oldShape.getParent() == currentShape : "Out-of-order shape change?" + "\nparentShape=" + currentShape + "\noldShape=" + oldShape + "\nnewShape=" + newShape; - return true; - } - - /** - * Check whether the extension arrays are in accordance with the description in the shape. - */ - @Override - protected final boolean checkExtensionArrayInvariants(Shape newShape) { - assert getShape() == newShape; - assert (getObjectStore(newShape) == null && newShape.getObjectArrayCapacity() == 0) || - (getObjectStore(newShape) != null && getObjectStore(newShape).length == newShape.getObjectArrayCapacity()); - if (newShape.hasPrimitiveArray()) { - assert (getPrimitiveStore(newShape) == null && newShape.getPrimitiveArrayCapacity() == 0) || - (getPrimitiveStore(newShape) != null && getPrimitiveStore(newShape).length == newShape.getPrimitiveArrayCapacity()); - } - return true; - } - - @Override - protected final DynamicObject cloneWithShape(Shape currentShape) { - assert this.getShape() == currentShape; - final DynamicObjectBasic clone = (DynamicObjectBasic) super.clone(); - if (this.getObjectStore(currentShape) != null) { - clone.setObjectStore(this.getObjectStore(currentShape).clone(), currentShape); - } - if (currentShape.hasPrimitiveArray() && this.getPrimitiveStore(currentShape) != null) { - clone.setPrimitiveStore(this.getPrimitiveStore(currentShape).clone(), currentShape); - } - return clone; - } - - protected final void reshape(ShapeImpl newShape) { - reshapeCount.inc(); - - ShapeImpl oldShape = getShape(); - ShapeImpl commonAncestor = ShapeImpl.findCommonAncestor(oldShape, newShape); - if (ObjectStorageOptions.TraceReshape) { - int limit = 150; - System.out.printf("RESHAPE\nOLD %s\nNEW %s\nLCA %s\nDIFF %s\n---\n", oldShape.toStringLimit(limit), newShape.toStringLimit(limit), commonAncestor.toStringLimit(limit), - ShapeImpl.diff(oldShape, newShape)); - } - - DynamicObject original = this.cloneWithShape(oldShape); - setShapeAndGrow(oldShape, newShape); - assert !((newShape.hasPrimitiveArray() && newShape.getPrimitiveArrayCapacity() == 0)) || getPrimitiveStore(newShape) == null; - copyProperties(original, commonAncestor); - assert checkExtensionArrayInvariants(newShape); - } - - static final SimpleObjectFieldLocation[] OBJECT_FIELD_LOCATIONS; - static final SimpleLongFieldLocation[] PRIMITIVE_FIELD_LOCATIONS; - - static final SimpleObjectFieldLocation OBJECT_ARRAY_LOCATION; - static final SimpleObjectFieldLocation PRIMITIVE_ARRAY_LOCATION; - - static { - int index; - - index = 0; - PRIMITIVE_FIELD_LOCATIONS = new SimpleLongFieldLocation[]{new SimpleLongFieldLocation(index++) { - @Override - public long getLong(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).primitive1; - } - - @Override - public void setLongInternal(DynamicObject store, long value) { - ((DynamicObjectBasic) store).primitive1 = value; - } - }, new SimpleLongFieldLocation(index++) { - @Override - public long getLong(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).primitive2; - } - - @Override - public void setLongInternal(DynamicObject store, long value) { - ((DynamicObjectBasic) store).primitive2 = value; - } - }, new SimpleLongFieldLocation(index++) { - @Override - public long getLong(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).primitive3; - } - - @Override - public void setLongInternal(DynamicObject store, long value) { - ((DynamicObjectBasic) store).primitive3 = value; - } - }}; - - index = 0; - OBJECT_FIELD_LOCATIONS = new SimpleObjectFieldLocation[]{new SimpleObjectFieldLocation(index++) { - @Override - public Object get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).object1; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).object1 = value; - } - }, new SimpleObjectFieldLocation(index++) { - @Override - public Object get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).object2; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).object2 = value; - } - }, new SimpleObjectFieldLocation(index++) { - @Override - public Object get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).object3; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).object3 = value; - } - }, new SimpleObjectFieldLocation(index++) { - @Override - public Object get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).object4; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).object4 = value; - } - }}; - - OBJECT_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { - @Override - public Object[] get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).objext; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).objext = (Object[]) value; - } - }; - - PRIMITIVE_ARRAY_LOCATION = new SimpleObjectFieldLocation(index++) { - @Override - public long[] get(DynamicObject store, boolean condition) { - return ((DynamicObjectBasic) store).primext; - } - - @Override - public void setInternal(DynamicObject store, Object value) { - ((DynamicObjectBasic) store).primext = (long[]) value; - } - }; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012, 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.object.basic; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; - -public final class ShapeBasic extends ShapeImpl { - public ShapeBasic(Layout layout, Object sharedData, ObjectType operations, int id) { - super(layout, operations, sharedData, id); - } - - public ShapeBasic(Layout layout, Object sharedData, ShapeImpl parent, ObjectType objectType, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { - super(layout, parent, objectType, sharedData, propertyMap, transition, allocator, id); - } - - @SuppressWarnings("hiding") - @Override - protected ShapeImpl createShape(Layout layout, Object sharedData, ShapeImpl parent, ObjectType objectType, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { - return new ShapeBasic(layout, sharedData, parent, objectType, propertyMap, transition, allocator, id); - } - - @Override - public ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { - return directReplaceProperty(oldProperty, newProperty); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Debug.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Debug.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +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.object; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.object.debug.*; - -class Debug { - private static Collection allShapes; - - static void registerShape(ShapeImpl newShape) { - allShapes.add(newShape); - } - - static { - if (ObjectStorageOptions.DumpShapes) { - allShapes = new ConcurrentLinkedQueue<>(); - } - - if (ObjectStorageOptions.DumpShapes) { - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - public void run() { - try (PrintWriter out = new PrintWriter("shapes.json", "UTF-8")) { - out.println("{\"shapes\": ["); - boolean first = true; - for (ShapeImpl shape : allShapes) { - if (!first) { - out.println(","); - } - first = false; - out.print(shape.accept(new JSONShapeVisitor())); - } - if (!first) { - out.println(); - } - out.println("]}"); - } catch (FileNotFoundException | UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - })); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DebugShapeVisitor.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DebugShapeVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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.object; - -import java.util.*; - -import com.oracle.truffle.api.object.*; - -public abstract class DebugShapeVisitor implements ShapeVisitor { - public R visitShape(Shape shape) { - return visitShape(shape, Collections.unmodifiableMap(((ShapeImpl) shape).getTransitionMapForRead())); - } - - public abstract R visitShape(Shape shape, Map transitions); - - public static String getId(Shape shape) { - return Integer.toHexString(shape.hashCode()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,381 +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.object; - -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.*; -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.Locations.ValueLocation; -import com.oracle.truffle.object.debug.*; - -public abstract class DynamicObjectImpl extends DynamicObject implements Cloneable { - private ShapeImpl shape; - - public static final DebugCounter reshapeCount = DebugCounter.create("Reshape count"); - - public DynamicObjectImpl(Shape shape) { - assert shape instanceof ShapeImpl; - initialize(shape); - setShape(shape); - - if (ObjectStorageOptions.Profile) { - trackObject(this); - } - } - - public Object getTypeIdentifier() { - return getShape(); - } - - @Override - public ShapeImpl getShape() { - return shape; - } - - protected void setShape(Shape shape) { - assert shape.getLayout().getType().isInstance(this); - this.shape = (ShapeImpl) shape; - } - - protected abstract void initialize(Shape initialShape); - - public final void setShapeAndResize(Shape newShape) { - setShapeAndResize(getShape(), newShape); - } - - @Override - public final void setShapeAndResize(Shape oldShape, Shape newShape) { - assert getShape() == oldShape : "wrong old shape"; - if (oldShape != newShape) { - setShape(newShape); - resizeStore(oldShape, newShape); - - assert checkExtensionArrayInvariants(newShape); - } - } - - /** - * Set shape to an immediate child of the current shape, optionally growing the extension array. - * Typically this would add a single property. Cannot shrink or grow more than one property at a - * time. - * - * @see #setShapeAndResize(Shape, Shape) - */ - @Override - public final void setShapeAndGrow(Shape oldShape, Shape newShape) { - assert getShape() == oldShape : "wrong old shape"; - if (oldShape != newShape) { - assert checkSetShape(oldShape, newShape); - - setShape(newShape); - growStore(oldShape, newShape); - - assert checkExtensionArrayInvariants(newShape); - } - } - - /** - * Simpler version of {@link #resizeStore} when the object is only increasing in size. - */ - private void growStore(Shape oldShape, Shape newShape) { - growObjectStore(oldShape, newShape); - if (((ShapeImpl) newShape).hasPrimitiveArray) { - growPrimitiveStore(oldShape, newShape); - } - } - - protected abstract void growObjectStore(Shape oldShape, Shape newShape); - - protected abstract void growPrimitiveStore(Shape oldShape, Shape newShape); - - private void resizeStore(Shape oldShape, Shape newShape) { - resizeObjectStore(oldShape, newShape); - if (((ShapeImpl) newShape).hasPrimitiveArray) { - resizePrimitiveStore(oldShape, newShape); - } - } - - protected abstract void resizePrimitiveStore(Shape oldShape, Shape newShape); - - protected abstract void resizeObjectStore(Shape oldShape, Shape newShape); - - /** - * Check whether fast transition is valid. - * - * @see #setShapeAndGrow - */ - private boolean checkSetShape(Shape oldShape, Shape newShape) { - Shape currentShape = getShape(); - assert oldShape != newShape : "Wrong old shape assumption?"; - assert newShape != currentShape : "Redundant shape change? shape=" + currentShape; - // assert oldShape == currentShape || (oldShape.getLastProperty() == ((EnterpriseLayout) - // oldShape.getLayout()).getPrimitiveArrayProperty() && oldShape.getParent() == - // currentShape) : "Out-of-order shape change?" + "\nparentShape=" + currentShape + - // "\noldShape=" + oldShape + "\nnewShape=" + newShape; - return true; - } - - /** - * Check whether the extension arrays are in accordance with the description in the shape. - */ - protected abstract boolean checkExtensionArrayInvariants(Shape newShape); - - @Override - protected final DynamicObject clone() { - try { - return (DynamicObject) super.clone(); - } catch (CloneNotSupportedException e) { - throw new IllegalStateException(); - } - } - - protected abstract DynamicObject cloneWithShape(Shape currentShape); - - void reshapeAfterDelete(final Shape newShape, final Shape deletedParentShape) { - DynamicObject original = this.cloneWithShape(getShape()); - setShapeAndResize(newShape); - copyProperties(original, deletedParentShape); - } - - public final void copyProperties(DynamicObject fromObject, Shape ancestor) { - ShapeImpl fromShape = (ShapeImpl) fromObject.getShape(); - ShapeImpl toShape = getShape(); - assert toShape.isRelated(ancestor); - assert toShape.isValid(); - assert ancestor.isValid(); - PropertyMap ancestorMap = ((ShapeImpl) ancestor).getPropertyMap(); - PropertyMap fromMap = fromShape.getPropertyMap(); - for (PropertyMap toMap = toShape.getPropertyMap(); !toMap.isEmpty() && toMap != ancestorMap; toMap = toMap.getParentMap()) { - Property toProperty = toMap.getLastProperty(); - Property fromProperty = fromMap.get(toProperty.getKey()); - - // copy only if property has a location and it's not the same as the source location - if (toProperty.getLocation() != null && !(toProperty.getLocation() instanceof ValueLocation) && !toProperty.getLocation().equals(fromProperty.getLocation())) { - toProperty.setInternal(this, fromProperty.get(fromObject, false)); - assert toShape.isValid(); - } - - if (fromProperty == fromMap.getLastProperty()) { - // no property is looked up twice, so we can skip over to parent - fromMap = fromMap.getParentMap(); - } - } - } - - @Override - @TruffleBoundary - public boolean changeFlags(Object id, int newFlags) { - Shape oldShape = getShape(); - Property existing = oldShape.getProperty(id); - if (existing != null) { - if (existing.getFlags() != newFlags) { - Property newProperty = existing.copyWithFlags(newFlags); - Shape newShape = oldShape.replaceProperty(existing, newProperty); - this.setShape(newShape); - } - return true; - } else { - return false; - } - } - - @Override - @TruffleBoundary - public boolean changeFlags(Object id, FlagsFunction updateFunction) { - Shape oldShape = getShape(); - Property existing = oldShape.getProperty(id); - if (existing != null) { - int newFlags = updateFunction.apply(existing.getFlags()); - if (existing.getFlags() != newFlags) { - Property newProperty = existing.copyWithFlags(newFlags); - Shape newShape = oldShape.replaceProperty(existing, newProperty); - this.setShape(newShape); - } - return true; - } else { - return false; - } - } - - public String debugDump(int level) { - return debugDump(0, level); - } - - public String debugDump(int level, int levelStop) { - List properties = this.getShape().getPropertyListInternal(true); - StringBuilder sb = new StringBuilder(properties.size() * 10); - sb.append("{\n"); - for (Property property : properties) { - indent(sb, level + 1); - - sb.append(property.getKey()); - sb.append('[').append(property.getLocation()).append(']'); - Object value = property.get(this, false); - if (value instanceof DynamicObjectImpl) { - if (level < levelStop) { - value = ((DynamicObjectImpl) value).debugDump(level + 1, levelStop); - } else { - value = value.toString(); - } - } - sb.append(": "); - sb.append(value); - if (property != properties.get(properties.size() - 1)) { - sb.append(","); - } - sb.append("\n"); - } - indent(sb, level); - sb.append("}"); - return sb.toString(); - } - - private static StringBuilder indent(StringBuilder sb, int level) { - for (int i = 0; i < level; i++) { - sb.append(' '); - } - return sb; - } - - @Override - public String toString() { - return getShape().getObjectType().toString(this); - } - - @Override - public boolean equals(Object obj) { - return getShape().getObjectType().equals(this, obj); - } - - @Override - public int hashCode() { - return getShape().getObjectType().hashCode(this); - } - - @Override - @TruffleBoundary - public Object get(Object id, Object defaultValue) { - Property existing = getShape().getProperty(id); - if (existing != null) { - return existing.get(this, false); - } else { - return defaultValue; - } - } - - @Override - @TruffleBoundary - public boolean set(Object id, Object value) { - Property existing = getShape().getProperty(id); - if (existing != null) { - existing.setGeneric(this, value, null); - return true; - } else { - return false; - } - } - - @Override - @TruffleBoundary - public void define(Object id, Object value, int flags) { - ShapeImpl oldShape = getShape(); - Property existing = oldShape.getProperty(id); - if (existing == null) { - updateShape(); - oldShape = getShape(); - Shape newShape = oldShape.addProperty(Property.create(id, oldShape.allocator().locationForValue(value, true, true), flags)); - updateShape(); - newShape.getLastProperty().setGeneric(this, value, oldShape, newShape); - } else { - defineExisting(id, value, flags, existing, oldShape); - } - } - - private void defineExisting(Object id, Object value, int flags, Property existing, ShapeImpl oldShape) { - if (existing.getFlags() == flags) { - existing.setGeneric(this, value, null); - } else { - Property newProperty = Property.create(id, oldShape.getLayout().existingLocationForValue(value, existing.getLocation(), oldShape), flags); - Shape newShape = oldShape.replaceProperty(existing, newProperty); - this.setShapeAndResize(newShape); - newProperty.setInternal(this, value); - } - } - - @Override - @TruffleBoundary - public void define(Object id, Object value, int flags, LocationFactory locationFactory) { - ShapeImpl oldShape = getShape(); - Property existing = oldShape.getProperty(id); - if (existing == null) { - updateShape(); - oldShape = getShape(); - Shape newShape = oldShape.addProperty(Property.create(id, locationFactory.createLocation(oldShape, value), flags)); - updateShape(); - newShape.getLastProperty().setGeneric(this, value, oldShape, newShape); - } else { - defineExisting(id, value, flags, existing, oldShape); - } - } - - @Override - @TruffleBoundary - public boolean delete(Object id) { - ShapeImpl oldShape = getShape(); - Property existing = oldShape.getProperty(id); - if (existing != null) { - ShapeImpl newShape = oldShape.removeProperty(existing); - this.reshapeAfterDelete(newShape, ShapeImpl.findCommonAncestor(oldShape, newShape)); - // TODO ancestor should be the parent of found property's shape - return true; - } else { - return false; - } - } - - @Override - public int size() { - return getShape().getPropertyCount(); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public final boolean updateShape() { - return getShape().getLayout().getStrategy().updateShape(this); - } - - private static void trackObject(DynamicObject obj) { - ShapeProfiler.getInstance().track(obj); - } - - @Override - public ForeignAccess getForeignAccess() { - return getShape().getForeignAccessFactory(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LayoutImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LayoutImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2012, 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.object; - -import java.util.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.api.object.Shape.Allocator; -import com.oracle.truffle.object.LocationImpl.EffectivelyFinalLocation; -import com.oracle.truffle.object.LocationImpl.TypedObjectLocation; -import com.oracle.truffle.object.Locations.ConstantLocation; -import com.oracle.truffle.object.Locations.DeclaredLocation; -import com.oracle.truffle.object.Locations.DualLocation; -import com.oracle.truffle.object.Locations.ValueLocation; -import com.oracle.truffle.object.ShapeImpl.BaseAllocator; - -public abstract class LayoutImpl extends Layout { - private static final int INT_TO_DOUBLE_FLAG = 1; - private static final int INT_TO_LONG_FLAG = 2; - - private final LayoutStrategy strategy; - private final Class clazz; - private final int allowedImplicitCasts; - - protected LayoutImpl(EnumSet allowedImplicitCasts, Class clazz, LayoutStrategy strategy) { - this.strategy = strategy; - this.clazz = clazz; - - this.allowedImplicitCasts = (allowedImplicitCasts.contains(ImplicitCast.IntToDouble) ? INT_TO_DOUBLE_FLAG : 0) | (allowedImplicitCasts.contains(ImplicitCast.IntToLong) ? INT_TO_LONG_FLAG : 0); - } - - @Override - public abstract DynamicObject newInstance(Shape shape); - - @Override - public Class getType() { - return clazz; - } - - @Override - public final Shape createShape(ObjectType operations, Object sharedData) { - return createShape(operations, sharedData, 0); - } - - @Override - public final Shape createShape(ObjectType operations) { - return createShape(operations, null); - } - - public boolean isAllowedIntToDouble() { - return (allowedImplicitCasts & INT_TO_DOUBLE_FLAG) != 0; - } - - public boolean isAllowedIntToLong() { - return (allowedImplicitCasts & INT_TO_LONG_FLAG) != 0; - } - - protected abstract boolean hasObjectExtensionArray(); - - protected abstract boolean hasPrimitiveExtensionArray(); - - protected abstract int getObjectFieldCount(); - - protected abstract int getPrimitiveFieldCount(); - - protected abstract Location getObjectArrayLocation(); - - protected abstract Location getPrimitiveArrayLocation(); - - protected abstract int objectFieldIndex(Location location); - - protected boolean isLocationAssignableFrom(Location destination, Location source) { - LayoutImpl layout = this; - if (destination.isFinal()) { - // allowed FinalLocation => FinalLocation - // allowed FinalIntLocation => Final{Int,Double}Location - // allowed: Final{Int,Double,TypedObject}Location => FinalObjectLocation - if (!source.isFinal()) { - return false; - } - } - - if (destination instanceof IntLocation) { - return (source instanceof IntLocation); - } else if (destination instanceof DoubleLocation) { - return (source instanceof DoubleLocation || (layout.isAllowedIntToDouble() && source instanceof IntLocation)); - } else if (destination instanceof LongLocation) { - return (source instanceof LongLocation || (layout.isAllowedIntToLong() && source instanceof IntLocation)); - } else if (destination instanceof BooleanLocation) { - return (source instanceof BooleanLocation); - } else if (destination instanceof TypedObjectLocation) { - return source instanceof TypedObjectLocation && ((TypedObjectLocation) destination).getType().isAssignableFrom(((TypedObjectLocation) source).getType()); - } else if (destination instanceof ValueLocation) { - return false; - } else { - assert destination instanceof ObjectLocation || destination instanceof DualLocation; - return true; - } - } - - protected Location existingLocationForValue(Object value, Location oldLocation, Shape oldShape) { - assert oldShape.getLayout() == this; - Location newLocation; - if (oldLocation instanceof IntLocation && value instanceof Integer) { - newLocation = oldLocation; - } else if (oldLocation instanceof DoubleLocation && (value instanceof Double || this.isAllowedIntToDouble() && value instanceof Integer)) { - newLocation = oldLocation; - } else if (oldLocation instanceof LongLocation && (value instanceof Long || this.isAllowedIntToLong() && value instanceof Long)) { - newLocation = oldLocation; - } else if (oldLocation instanceof DeclaredLocation) { - return oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)); - } else if (oldLocation instanceof ConstantLocation) { - return LocationImpl.valueEquals(oldLocation.get(null, false), value) ? oldLocation : new Locations.ConstantLocation(value); - } else if (oldLocation instanceof TypedObjectLocation && !((TypedObjectLocation) oldLocation).getType().isAssignableFrom(value.getClass())) { - newLocation = (((TypedObjectLocation) oldLocation).toUntypedLocation()); - } else if (oldLocation instanceof DualLocation) { - if (oldLocation.canStore(value)) { - newLocation = oldLocation; - } else { - newLocation = ((BaseAllocator) oldShape.allocator()).locationForValueUpcast(value, oldLocation); - } - } else if (oldLocation instanceof ObjectLocation) { - newLocation = oldLocation; - } else { - return oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.NonNull)); - } - if (newLocation instanceof EffectivelyFinalLocation) { - newLocation = ((EffectivelyFinalLocation) newLocation).toNonFinalLocation(); - } - return newLocation; - } - - /** - * Is this property an upcast of the other property? - * - * @param other the property being compared to - * @return true if this is a upcast of the other property, false otherwise - */ - public boolean isPropertyUpcastOf(Property thiz, Property other) { - if (thiz.getLocation() != null && other.getLocation() != null && other.getKey().equals(thiz.getKey()) && other.getFlags() == thiz.getFlags()) { - if (isLocationAssignableFrom(thiz.getLocation(), other.getLocation())) { - return true; - } - } - return false; - } - - @Override - public abstract Allocator createAllocator(); - - public LayoutStrategy getStrategy() { - return strategy; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LayoutStrategy.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LayoutStrategy.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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.object; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.ShapeImpl.BaseAllocator; - -public interface LayoutStrategy { - boolean updateShape(DynamicObject object); - - Shape returnCached(Shape newShape); - - Shape ensureSpace(Shape shape, Location location); - - boolean isAutoExtArray(); - - Property generalizeProperty(DynamicObject object, Property oldProperty, Object value); - - Property generalizeProperty(DynamicObject object, Property oldProperty, Object value, Shape oldShape, Shape newShape); - - BaseAllocator createAllocator(Layout shape); - - BaseAllocator createAllocator(Shape shape); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LocationImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/LocationImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +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.object; - -import com.oracle.truffle.api.object.*; - -public abstract class LocationImpl extends Location { - - public interface EffectivelyFinalLocation { - T toNonFinalLocation(); - } - - public interface TypedObjectLocation extends ObjectLocation { - T toUntypedLocation(); - } - - public interface InternalLongLocation extends LongLocation { - void setLongInternal(DynamicObject store, long value); - } - - public interface LocationVisitor { - void visitObjectField(int index, int count); - - void visitObjectArray(int index, int count); - - void visitPrimitiveField(int index, int count); - - void visitPrimitiveArray(int index, int count); - } - - @Override - public void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { - setInternal(store, value); - } - - @Override - protected final Object getInternal(DynamicObject store) { - throw new UnsupportedOperationException(); - } - - @Override - protected abstract void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException; - - @Override - public final boolean canSet(DynamicObject store, Object value) { - return canStore(value) && canStoreFinal(store, value); - } - - @Override - public boolean canStore(Object value) { - return true; - } - - @SuppressWarnings("unused") - protected boolean canStoreFinal(DynamicObject store, Object value) { - return true; - } - - @Override - public boolean isFinal() { - return false; - } - - @Override - public boolean isConstant() { - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (isFinal() ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Location other = (Location) obj; - if (isFinal() != other.isFinal()) { - return false; - } - return true; - } - - @Override - public String toString() { - String finalString = isFinal() ? "f" : ""; - String typeString = this instanceof IntLocation ? "i" : (this instanceof DoubleLocation ? "d" : (this instanceof BooleanLocation ? "b" - : (this instanceof TypedLocation ? ((TypedLocation) this).getType().getSimpleName() : "o"))); - return finalString + typeString + getWhereString(); - } - - protected String getWhereString() { - return ""; - } - - /** - * Get the number of object array elements this location requires. - */ - public int objectArrayCount() { - return 0; - } - - /** - * Get the number of in-object {@link Object} fields this location requires. - */ - public int objectFieldCount() { - return 0; - } - - /** - * Get the number of in-object primitive fields this location requires. - */ - public int primitiveFieldCount() { - return 0; - } - - /** - * Get the number of primitive array elements this location requires. - */ - public int primitiveArrayCount() { - return 0; - } - - /** - * Accept a visitor for location allocation for this and every nested location. - * - * @param locationVisitor visitor to be notified of every allocated slot in use by this location - */ - public abstract void accept(LocationVisitor locationVisitor); - - /** - * Boxed values need to be compared by value not by reference. - * - * The first parameter should be the one with the more precise type information. - * - * For sets to final locations, otherValue.equals(thisValue) seems more beneficial, since we - * usually know more about the value to be set. - */ - public static boolean valueEquals(Object val1, Object val2) { - return val1 == val2 || (val1 != null && val1.equals(val2)); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Locations.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Locations.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,323 +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.object; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.object.*; - -/** - * Property location. - * - * @see Location - * @see Shape - * @see Property - * @see DynamicObject - */ -public abstract class Locations { - public abstract static class ValueLocation extends LocationImpl { - - private final Object value; - - public ValueLocation(Object value) { - assert !(value instanceof Location); - this.value = value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((value == null) ? 0 : 0 /* value.hashCode() */); - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - ValueLocation other = (ValueLocation) obj; - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.equals(other.value)) { - return false; - } - return true; - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return value; - } - - @Override - public final void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { - if (!canStoreFinal(store, value)) { - throw finalLocation(); - } - } - - @Override - protected boolean canStoreFinal(DynamicObject store, Object val) { - return valueEquals(this.value, val); - } - - @Override - public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (!canStoreFinal(store, value)) { - CompilerDirectives.transferToInterpreter(); - throw new UnsupportedOperationException(); - } - } - - @Override - public String toString() { - return "=" + String.valueOf(value); - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - } - } - - public static final class ConstantLocation extends ValueLocation { - - public ConstantLocation(Object value) { - super(value); - } - - @Override - public boolean isConstant() { - return true; - } - } - - public static final class DeclaredLocation extends ValueLocation { - - public DeclaredLocation(Object value) { - super(value); - } - } - - public static class DualLocation extends LocationImpl implements TypedLocation { - protected final InternalLongLocation primitiveLocation; - protected final ObjectLocation objectLocation; - protected final LayoutImpl layout; - private final Class type; - - public DualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, LayoutImpl layout) { - this(primitiveLocation, objectLocation, layout, null); - } - - public DualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, LayoutImpl layout, Class type) { - this.primitiveLocation = primitiveLocation; - this.objectLocation = objectLocation; - this.layout = layout; - this.type = type; - } - - @Override - public Object get(DynamicObject store, boolean condition) { - if (type == Object.class) { - return objectLocation.get(store, condition); - } else { - long rawValue = primitiveLocation.getLong(store, condition); - if (type == int.class) { - return (int) rawValue; - } else if (type == long.class) { - return rawValue; - } else if (type == double.class) { - return Double.longBitsToDouble(rawValue); - } else if (type == boolean.class) { - return rawValue != 0; - } else { - CompilerDirectives.transferToInterpreter(); - throw new IllegalStateException(); - } - } - } - - @Override - public void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (type == Object.class) { - ((LocationImpl) objectLocation).setInternal(store, value); - } else { - long rawValue; - if (type == int.class && value instanceof Integer) { - rawValue = (int) value; - } else if (type == long.class && value instanceof Long) { - rawValue = (long) value; - } else if (type == long.class && layout.isAllowedIntToLong() && value instanceof Integer) { - rawValue = (int) value; - } else if (type == double.class && value instanceof Double) { - rawValue = Double.doubleToRawLongBits((double) value); - } else if (type == double.class && layout.isAllowedIntToDouble() && value instanceof Integer) { - rawValue = Double.doubleToRawLongBits((int) value); - } else if (type == boolean.class && value instanceof Boolean) { - rawValue = (boolean) value ? 1 : 0; - } else { - throw incompatibleLocation(); - } - - primitiveLocation.setLongInternal(store, rawValue); - } - } - - @Override - public int primitiveFieldCount() { - return ((LocationImpl) primitiveLocation).primitiveFieldCount(); - } - - @Override - public int primitiveArrayCount() { - return ((LocationImpl) primitiveLocation).primitiveArrayCount(); - } - - @Override - public int objectFieldCount() { - return ((LocationImpl) objectLocation).objectFieldCount(); - } - - @Override - public int objectArrayCount() { - return ((LocationImpl) objectLocation).objectArrayCount(); - } - - @Override - public final void accept(LocationVisitor locationVisitor) { - ((LocationImpl) primitiveLocation).accept(locationVisitor); - ((LocationImpl) objectLocation).accept(locationVisitor); - } - - @Override - public String toString() { - return objectLocation.toString() + "," + primitiveLocation.toString() + "," + type; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - DualLocation other = (DualLocation) obj; - return getObjectLocation().equals(other.getObjectLocation()) && primitiveLocation.equals(other.primitiveLocation) && layout.equals(other.layout) && Objects.equals(type, other.type); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (getObjectLocation() == null ? 0 : getObjectLocation().hashCode()); - result = prime * result + (primitiveLocation == null ? 0 : primitiveLocation.hashCode()); - result = prime * result + (type == null ? 0 : type.hashCode()); - return result; - } - - public ObjectLocation getObjectLocation() { - return objectLocation; - } - - public DualLocation changeType(Class newType) { - return new DualLocation(primitiveLocation, objectLocation, layout, newType); - } - - public Class getType() { - return type; - } - - public boolean isNonNull() { - return false; - } - - @Override - public boolean canStore(Object value) { - if (type == null) { - return false; - } else if (type == int.class) { - return value instanceof Integer; - } else if (type == long.class) { - return value instanceof Long || (layout.isAllowedIntToLong() && value instanceof Integer); - } else if (type == double.class) { - return value instanceof Double || (layout.isAllowedIntToDouble() && value instanceof Integer); - } else if (type == boolean.class) { - return value instanceof Boolean; - } else if (type == Object.class) { - return true; - } else { - throw new IllegalStateException(); - } - } - } - - public static class DeclaredDualLocation extends DualLocation { - private final Object defaultValue; - - public DeclaredDualLocation(InternalLongLocation primitiveLocation, ObjectLocation objectLocation, Object defaultValue, LayoutImpl layout) { - super(primitiveLocation, objectLocation, layout); - this.defaultValue = defaultValue; - } - - @Override - public Object get(DynamicObject store, boolean condition) { - return defaultValue; - } - - @Override - public void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { - if (valueEquals(defaultValue, value)) { - return; - } else { - throw incompatibleLocation(); - } - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj) && Objects.equals(defaultValue, ((DeclaredDualLocation) obj).defaultValue); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public DualLocation changeType(Class newType) { - return new DualLocation(primitiveLocation, objectLocation, layout, newType); - } - - @Override - public boolean canStore(Object value) { - return valueEquals(defaultValue, value); - } - - @Override - public String toString() { - return objectLocation.toString() + "," + primitiveLocation.toString() + ",unset"; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ObjectStorageOptions.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ObjectStorageOptions.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2012, 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.object; - -import static com.oracle.truffle.api.object.Layout.*; - -public class ObjectStorageOptions { - // Shape configuration - /** Primitive location switch. */ - public static boolean PrimitiveLocations = booleanOption(OPTION_PREFIX + "PrimitiveLocations", true); - public static boolean IntegerLocations = booleanOption(OPTION_PREFIX + "IntegerLocations", true); - public static boolean DoubleLocations = booleanOption(OPTION_PREFIX + "DoubleLocations", true); - public static boolean LongLocations = booleanOption(OPTION_PREFIX + "LongLocations", true); - public static boolean BooleanLocations = booleanOption(OPTION_PREFIX + "BooleanLocations", true); - public static boolean TypedObjectLocations = booleanOption(OPTION_PREFIX + "TypedObjectLocations", true); - - /** Allocation of in-object fields. */ - public static boolean InObjectFields = booleanOption(OPTION_PREFIX + "InObjectFields", true); - - // Debug options (should be final) - public static final boolean TraceReshape = booleanOption(OPTION_PREFIX + "TraceReshape", false); - public static final boolean DumpShapes = booleanOption(OPTION_PREFIX + "DumpShapes", false); - - public static final boolean Profile = booleanOption(OPTION_PREFIX + "Profile", false); - public static final int ProfileTopResults = Integer.getInteger(OPTION_PREFIX + "ProfileTopResults", -1); - - public static boolean booleanOption(String name, boolean defaultValue) { - String value = System.getProperty(name); - return value == null ? defaultValue : value.equalsIgnoreCase("true"); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2012, 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.object; - -import java.util.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.Locations.DeclaredLocation; - -/** - * Property objects represent the mapping between property identifiers (keys) and storage locations. - * Optionally, properties may have metadata attached to them. - */ -public class PropertyImpl extends Property { - private final Object key; - private final Location location; - private final int flags; - private final boolean shadow; - private final boolean relocatable; - - /** - * Generic, usual-case constructor for properties storing at least a name. - * - * @param key the name of the property - * @param location the storage location used to access the property - * @param flags property flags (optional) - */ - protected PropertyImpl(Object key, Location location, int flags, boolean shadow, boolean relocatable) { - this.key = Objects.requireNonNull(key); - this.location = Objects.requireNonNull(location); - this.flags = flags; - this.shadow = shadow; - this.relocatable = relocatable; - } - - public PropertyImpl(Object name, Location location, int flags) { - this(name, location, flags, false, true); - } - - @Override - public final Object getKey() { - return key; - } - - @Override - public int getFlags() { - return flags; - } - - @Override - public Property relocate(Location newLocation) { - if (!getLocation().equals(newLocation) && relocatable) { - return construct(key, newLocation, flags); - } - return this; - } - - @Override - public final Object get(DynamicObject store, Shape shape) { - return getLocation().get(store, shape); - } - - @Override - public final Object get(DynamicObject store, boolean condition) { - return getLocation().get(store, condition); - } - - @Override - public final void setInternal(DynamicObject store, Object value) { - try { - ((LocationImpl) getLocation()).setInternal(store, value); - } catch (IncompatibleLocationException e) { - throw new IllegalStateException(); - } - } - - @Override - public final void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { - assert shape == null || store.getShape() == shape : "wrong shape"; - getLocation().set(store, value, shape); - } - - @Override - public final void setSafe(DynamicObject store, Object value, Shape shape) { - assert shape == null || store.getShape() == shape : "wrong shape"; - try { - getLocation().set(store, value, shape); - } catch (IncompatibleLocationException | FinalLocationException ex) { - throw new IllegalStateException(); - } - } - - @Override - public final void setGeneric(DynamicObject store, Object value, Shape shape) { - assert shape == null || store.getShape() == shape : "wrong shape"; - try { - set(store, value, shape); - } catch (IncompatibleLocationException | FinalLocationException ex) { - setSlowCase(store, value); - } - } - - @Override - public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { - assert store.getShape() == oldShape : "wrong shape"; - assert newShape.isValid(); - assert getLocation() != null; - getLocation().set(store, value, oldShape, newShape); - } - - @Override - public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { - assert store.getShape() == oldShape : "wrong old shape"; - assert newShape.isValid(); - assert getLocation() != null; - try { - getLocation().set(store, value, oldShape, newShape); - } catch (IncompatibleLocationException ex) { - throw new IllegalStateException(); - } - } - - @Override - public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { - assert store.getShape() == oldShape : "wrong old shape"; - assert newShape.isValid(); - assert getLocation() != null; - try { - getLocation().set(store, value, oldShape, newShape); - } catch (IncompatibleLocationException ex) { - setWithShapeSlowCase(store, value, oldShape, newShape); - } - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - - PropertyImpl other = (PropertyImpl) obj; - return key.equals(other.key) && location.equals(other.location) && flags == other.flags && shadow == other.shadow && relocatable == other.relocatable; - } - - @Override - public boolean isSame(Property obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - - PropertyImpl other = (PropertyImpl) obj; - return key.equals(other.key) && flags == other.flags; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getClass().hashCode(); - result = prime * result + key.hashCode(); - result = prime * result + location.hashCode(); - result = prime * result + flags; - return result; - } - - @Override - public String toString() { - return "\"" + key + "\"" + ":" + location; - } - - @Override - public final Location getLocation() { - return location; - } - - private void setSlowCase(DynamicObject store, Object value) { - if (getLocation() instanceof DeclaredLocation) { - setDeclaredLocation(store, value); - } else { - generalize(store, value); - } - } - - private void setDeclaredLocation(DynamicObject store, Object value) { - store.updateShape(); - Shape oldShape = store.getShape(); - Shape newShape = oldShape.addProperty(this.relocateShadow(oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)))); - store.updateShape(); - newShape.getLastProperty().setGeneric(store, value, oldShape, newShape); - } - - private Property generalize(DynamicObject store, Object value) { - return ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value); - } - - private void setWithShapeSlowCase(DynamicObject store, Object value, Shape oldShape, Shape newShape) { - ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value, oldShape, newShape); - } - - @Override - public final boolean isHidden() { - return key instanceof HiddenKey; - } - - @Override - public final boolean isShadow() { - return shadow; - } - - private Property relocateShadow(Location newLocation) { - assert !isShadow() && getLocation() instanceof DeclaredLocation && relocatable; - return new PropertyImpl(key, newLocation, flags, true, relocatable); - } - - @SuppressWarnings("hiding") - protected Property construct(Object name, Location location, int flags) { - return new PropertyImpl(name, location, flags, shadow, relocatable); - } - - @Override - public Property copyWithFlags(int newFlags) { - return construct(key, location, newFlags); - } - - @Override - public Property copyWithRelocatable(boolean newRelocatable) { - if (this.relocatable != newRelocatable) { - return new PropertyImpl(key, location, flags, shadow, newRelocatable); - } - return this; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +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.object; - -import java.util.*; - -import com.oracle.truffle.api.object.*; - -public final class PropertyMap implements Map { - private final PropertyMap car; - private final Property cdr; - private final int size; - - private static final PropertyMap EMPTY = new PropertyMap(); - - private PropertyMap() { - this.car = null; - this.cdr = null; - this.size = 0; - } - - private PropertyMap(PropertyMap parent, Property added) { - this.car = Objects.requireNonNull(parent); - this.cdr = added; - this.size = parent.size + 1; - } - - public static PropertyMap empty() { - return EMPTY; - } - - public int size() { - return size; - } - - public boolean isEmpty() { - return size() == 0; - } - - public boolean containsKey(Object key) { - for (Map.Entry entry : reverseOrderEntrySet()) { - if (entry.getKey().equals(key)) { - return true; - } - } - return false; - } - - public boolean containsValue(Object value) { - for (Map.Entry entry : reverseOrderEntrySet()) { - if (entry.getValue().equals(value)) { - return true; - } - } - return false; - } - - public Property get(Object key) { - for (Map.Entry entry : reverseOrderEntrySet()) { - if (entry.getKey().equals(key)) { - return entry.getValue(); - } - } - return null; - } - - public Property put(Object key, Property value) { - throw unmodifiableException(); - } - - public Property remove(Object key) { - throw unmodifiableException(); - } - - public void putAll(Map m) { - throw unmodifiableException(); - } - - public void clear() { - throw unmodifiableException(); - } - - public Set keySet() { - return new AbstractSet() { - @Override - public Iterator iterator() { - Object[] keys = new Object[size()]; - Iterator> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - keys[pos] = iterator.next().getKey(); - } - return Arrays.asList(keys).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Collection values() { - return new AbstractSet() { - @Override - public Iterator iterator() { - Property[] values = new Property[size()]; - Iterator> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - values[pos] = iterator.next().getValue(); - } - return Arrays.asList(values).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set> entrySet() { - return new AbstractSet>() { - @Override - public Iterator> iterator() { - @SuppressWarnings("unchecked") - Map.Entry[] entries = (Map.Entry[]) new Map.Entry[size()]; - Iterator> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - entries[pos] = iterator.next(); - } - return Arrays.asList(entries).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set> reverseOrderEntrySet() { - return new AbstractSet>() { - @Override - public Iterator> iterator() { - return new Iterator>() { - PropertyMap current = PropertyMap.this; - - public Entry next() { - if (hasNext()) { - try { - return new MapEntryImpl(current.cdr); - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set reverseOrderKeys() { - return new AbstractSet() { - @Override - public Iterator iterator() { - return new Iterator() { - PropertyMap current = PropertyMap.this; - - public Object next() { - if (hasNext()) { - try { - return current.cdr.getKey(); - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set reverseOrderValues() { - return new AbstractSet() { - @Override - public Iterator iterator() { - return new Iterator() { - PropertyMap current = PropertyMap.this; - - public Property next() { - if (hasNext()) { - try { - return current.cdr; - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - private static final class MapEntryImpl implements Map.Entry { - private final Property backingProperty; - - public MapEntryImpl(Property backingProperty) { - this.backingProperty = backingProperty; - } - - public Object getKey() { - return backingProperty.getKey(); - } - - public Property getValue() { - return backingProperty; - } - - public Property setValue(Property value) { - throw unmodifiableException(); - } - } - - private static UnsupportedOperationException unmodifiableException() { - throw new UnsupportedOperationException("unmodifiable"); - } - - public PropertyMap putCopy(Property value) { - return new PropertyMap(this, value); - } - - public PropertyMap removeCopy(Property value) { - Deque shelve = new ArrayDeque<>(); - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(value)) { - PropertyMap newMap = current.getParentMap(); - for (Property property : shelve) { - newMap = newMap.putCopy(property); - } - return newMap; - } else { - shelve.push(current.getLastProperty()); - current = current.getParentMap(); - } - } - return this; - } - - public PropertyMap replaceCopy(Property oldValue, Property newValue) { - Deque shelve = new ArrayDeque<>(); - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(oldValue)) { - PropertyMap newMap = current.getParentMap(); - newMap = newMap.putCopy(newValue); - for (Property property : shelve) { - newMap = newMap.putCopy(property); - } - return newMap; - } else { - shelve.push(current.getLastProperty()); - current = current.getParentMap(); - } - } - return this; - } - - public PropertyMap getOwningMap(Property value) { - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(value)) { - return current; - } - current = current.getParentMap(); - } - return null; - } - - PropertyMap getParentMap() { - return car; - } - - public Property getLastProperty() { - return cdr; - } - - @Override - public String toString() { - return values().toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1074 +0,0 @@ -/* - * Copyright (c) 2012, 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.object; - -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.object.LocationImpl.InternalLongLocation; -import com.oracle.truffle.object.LocationImpl.LocationVisitor; -import com.oracle.truffle.object.Locations.ConstantLocation; -import com.oracle.truffle.object.Locations.DeclaredDualLocation; -import com.oracle.truffle.object.Locations.DeclaredLocation; -import com.oracle.truffle.object.Locations.DualLocation; -import com.oracle.truffle.object.Locations.ValueLocation; -import com.oracle.truffle.object.Transition.AddPropertyTransition; -import com.oracle.truffle.object.Transition.DirectReplacePropertyTransition; -import com.oracle.truffle.object.Transition.ObjectTypeTransition; -import com.oracle.truffle.object.Transition.PropertyTransition; -import com.oracle.truffle.object.Transition.RemovePropertyTransition; -import com.oracle.truffle.object.Transition.ReservePrimitiveArrayTransition; - -/** - * Shape objects create a mapping of Property objects to indexes. The mapping of those indexes to an - * actual store is not part of Shape's role, but JSObject's. Shapes are immutable; adding or - * deleting a property yields a new Shape which links to the old one. This allows inline caching to - * simply check the identity of an object's Shape to determine if the cache is valid. There is one - * exception to this immutability, the transition map, but that is used simply to assure that an - * identical series of property additions and deletions will yield the same Shape object. - * - * @see DynamicObject - * @see Property - * @see Locations - */ -public abstract class ShapeImpl extends Shape { - private final int id; - - protected final LayoutImpl layout; - protected final ObjectType objectType; - protected final ShapeImpl parent; - protected final PropertyMap propertyMap; - - private final Object extraData; - private final Object sharedData; - private final ShapeImpl root; - - protected final int objectArraySize; - protected final int objectArrayCapacity; - protected final int objectFieldSize; - protected final int primitiveFieldSize; - protected final int primitiveArraySize; - protected final int primitiveArrayCapacity; - protected final boolean hasPrimitiveArray; - - protected final int depth; - protected final int propertyCount; - - protected final Assumption validAssumption; - @CompilationFinal protected volatile Assumption leafAssumption; - - /** - * Shape transition map; lazily initialized. - * - * @see #getTransitionMapForRead() - * @see #getTransitionMapForWrite() - */ - private volatile Map transitionMap; - - private final Transition transitionFromParent; - - /** - * Private constructor. - * - * @param parent predecessor shape - * @param transitionFromParent direct transition from parent shape - * @see #ShapeImpl(Layout, ShapeImpl, ObjectType, Object, PropertyMap, Transition, - * BaseAllocator, int) - */ - private ShapeImpl(Layout layout, ShapeImpl parent, ObjectType objectType, Object sharedData, PropertyMap propertyMap, Transition transitionFromParent, int objectArraySize, int objectFieldSize, - int primitiveFieldSize, int primitiveArraySize, boolean hasPrimitiveArray, int id) { - this.layout = (LayoutImpl) layout; - this.objectType = Objects.requireNonNull(objectType); - this.propertyMap = Objects.requireNonNull(propertyMap); - this.root = parent != null ? parent.getRoot() : this; - this.parent = parent; - this.transitionFromParent = transitionFromParent; - this.objectArraySize = objectArraySize; - this.objectArrayCapacity = capacityFromSize(objectArraySize); - this.objectFieldSize = objectFieldSize; - this.primitiveFieldSize = primitiveFieldSize; - this.primitiveArraySize = primitiveArraySize; - this.primitiveArrayCapacity = capacityFromSize(primitiveArraySize); - this.hasPrimitiveArray = hasPrimitiveArray; - - if (parent != null) { - this.propertyCount = makePropertyCount(parent, propertyMap); - this.depth = parent.depth + 1; - } else { - this.propertyCount = 0; - this.depth = 0; - } - - this.validAssumption = createValidAssumption(); - - this.id = id; - shapeCount.inc(); - - this.sharedData = sharedData; - this.extraData = objectType.createShapeData(this); - - debugRegisterShape(this); - } - - protected ShapeImpl(Layout layout, ShapeImpl parent, ObjectType operations, Object sharedData, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { - this(layout, parent, operations, sharedData, propertyMap, transition, ((BaseAllocator) allocator).objectArraySize, ((BaseAllocator) allocator).objectFieldSize, - ((BaseAllocator) allocator).primitiveFieldSize, ((BaseAllocator) allocator).primitiveArraySize, ((BaseAllocator) allocator).hasPrimitiveArray, id); - } - - @SuppressWarnings("hiding") - protected abstract ShapeImpl createShape(Layout layout, Object sharedData, ShapeImpl parent, ObjectType operations, PropertyMap propertyMap, Transition transition, Allocator allocator, int id); - - protected ShapeImpl(Layout layout, ObjectType operations, Object sharedData, int id) { - this(layout, null, operations, sharedData, PropertyMap.empty(), null, layout.createAllocator(), id); - } - - private static int makePropertyCount(ShapeImpl parent, PropertyMap propertyMap) { - return parent.propertyCount + ((propertyMap.size() > parent.propertyMap.size() && !propertyMap.getLastProperty().isHidden() && !propertyMap.getLastProperty().isShadow()) ? 1 : 0); - } - - @Override - public final Property getLastProperty() { - return propertyMap.getLastProperty(); - } - - @Override - public final int getId() { - return this.id; - } - - /** - * Calculate array size for the given number of elements. - */ - private static int capacityFromSize(int size) { - if (size == 0) { - return 0; - } else if (size < 4) { - return 4; - } else if (size < 32) { - return ((size + 7) / 8) * 8; - } else { - return ((size + 15) / 16) * 16; - } - } - - @Override - public final int getObjectArraySize() { - return objectArraySize; - } - - @Override - public final int getObjectFieldSize() { - return objectFieldSize; - } - - @Override - public final int getPrimitiveFieldSize() { - return primitiveFieldSize; - } - - @Override - public final int getObjectArrayCapacity() { - return objectArrayCapacity; - } - - @Override - public final int getPrimitiveArrayCapacity() { - return primitiveArrayCapacity; - } - - @Override - public final int getPrimitiveArraySize() { - return primitiveArraySize; - } - - @Override - public final boolean hasPrimitiveArray() { - return hasPrimitiveArray; - } - - /** - * Get the (parent) shape that holds the given property. - */ - public final ShapeImpl getShapeFromProperty(Object propertyName) { - ShapeImpl current = this; - while (current != getRoot()) { - if (current.getTransitionFromParent() instanceof AddPropertyTransition && ((AddPropertyTransition) current.getTransitionFromParent()).getProperty().getKey().equals(propertyName)) { - return current; - } - current = current.getParent(); - } - - return null; - } - - /** - * Get the (parent) shape that holds the given property. - */ - public final ShapeImpl getShapeFromProperty(Property prop) { - ShapeImpl current = this; - while (current != getRoot()) { - if (current.getTransitionFromParent() instanceof AddPropertyTransition && ((AddPropertyTransition) current.getTransitionFromParent()).getProperty().equals(prop)) { - return current; - } - current = current.parent; - } - - return null; - } - - /** - * Get a property entry by string name. - * - * @param key the name to look up - * @return a Property object, or null if not found - */ - @Override - @TruffleBoundary - public Property getProperty(Object key) { - return propertyMap.get(key); - } - - protected final void addDirectTransition(Transition transition, ShapeImpl next) { - assert next.getParent() == this && transition.isDirect(); - addTransitionInternal(transition, next); - } - - public final void addIndirectTransition(Transition transition, ShapeImpl next) { - assert next.getParent() != this && !transition.isDirect(); - addTransitionInternal(transition, next); - } - - private void addTransitionInternal(Transition transition, ShapeImpl next) { - getTransitionMapForWrite().put(transition, next); - } - - public final Map getTransitionMapForRead() { - return transitionMap != null ? transitionMap : Collections. emptyMap(); - } - - private Map getTransitionMapForWrite() { - if (transitionMap != null) { - return transitionMap; - } else { - synchronized (getMutex()) { - if (transitionMap != null) { - return transitionMap; - } - invalidateLeafAssumption(); - return transitionMap = new ConcurrentHashMap<>(); - } - } - } - - public final PropertyMap getPropertyMap() { - return propertyMap; - } - - protected final ShapeImpl queryTransition(Transition transition) { - ShapeImpl cachedShape = this.getTransitionMapForRead().get(transition); - if (cachedShape != null) { // Shape already exists? - shapeCacheHitCount.inc(); - return (ShapeImpl) layout.getStrategy().returnCached(cachedShape); - } - shapeCacheMissCount.inc(); - - return null; - } - - /** - * Add a new property in the map, yielding a new or cached Shape object. - * - * @param property the property to add - * @return the new Shape - */ - @TruffleBoundary - @Override - public ShapeImpl addProperty(Property property) { - assert isValid(); - onPropertyTransition(property); - return addPropertyInternal(property); - } - - private void onPropertyTransition(Property property) { - if (sharedData instanceof ShapeListener) { - ((ShapeListener) sharedData).onPropertyTransition(property.getKey()); - } - } - - /** - * Add a new property in the map, yielding a new or cached Shape object. - * - * In contrast to {@link ShapeImpl#addProperty(Property)}, this method does not care about - * obsolete shapes. - * - * @see #addProperty(Property) - */ - private ShapeImpl addPropertyInternal(Property prop) { - CompilerAsserts.neverPartOfCompilation(); - assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property " + prop.getKey(); - - AddPropertyTransition addTransition = new AddPropertyTransition(prop); - ShapeImpl cachedShape = queryTransition(addTransition); - if (cachedShape != null) { - return cachedShape; - } - - ShapeImpl oldShape = (ShapeImpl) layout.getStrategy().ensureSpace(this, prop.getLocation()); - - ShapeImpl newShape = makeShapeWithAddedProperty(oldShape, addTransition); - oldShape.addDirectTransition(addTransition, newShape); - return newShape; - } - - protected ShapeImpl cloneRoot(ShapeImpl from, Object newSharedData) { - return createShape(from.layout, newSharedData, null, from.objectType, from.propertyMap, null, from.allocator(), from.id); - } - - /** - * Create a separate clone of a shape. - * - * @param newParent the cloned parent shape - */ - protected final ShapeImpl cloneOnto(ShapeImpl newParent) { - ShapeImpl from = this; - ShapeImpl newShape = createShape(newParent.layout, newParent.sharedData, newParent, from.objectType, from.propertyMap, from.transitionFromParent, from.allocator(), newParent.id); - - shapeCloneCount.inc(); - - // (aw) need to have this transition for obsolescence - newParent.addDirectTransition(from.transitionFromParent, newShape); - return newShape; - } - - public final Transition getTransitionFromParent() { - return transitionFromParent; - } - - /** - * Create a new shape that adds a property to the parent shape. - */ - private static ShapeImpl makeShapeWithAddedProperty(ShapeImpl parent, AddPropertyTransition addTransition) { - Property addend = addTransition.getProperty(); - BaseAllocator allocator = parent.allocator().addLocation(addend.getLocation()); - - PropertyMap newPropertyMap = parent.propertyMap.putCopy(addend); - - ShapeImpl newShape = parent.createShape(parent.layout, parent.sharedData, parent, parent.objectType, newPropertyMap, addTransition, allocator, parent.id); - assert ((LocationImpl) addend.getLocation()).primitiveArrayCount() == 0 || newShape.hasPrimitiveArray; - assert newShape.depth == allocator.depth; - return newShape; - } - - /** - * Create a new shape that reserves the primitive extension array field. - */ - private static ShapeImpl makeShapeWithPrimitiveExtensionArray(ShapeImpl parent, Transition transition) { - assert parent.getLayout().hasPrimitiveExtensionArray(); - assert !parent.hasPrimitiveArray(); - BaseAllocator allocator = parent.allocator().addLocation(parent.getLayout().getPrimitiveArrayLocation()); - ShapeImpl newShape = parent.createShape(parent.layout, parent.sharedData, parent, parent.objectType, parent.propertyMap, transition, allocator, parent.id); - assert newShape.hasPrimitiveArray(); - assert newShape.depth == allocator.depth; - return newShape; - } - - private ShapeImpl addPrimitiveExtensionArray() { - assert layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray(); - Transition transition = new ReservePrimitiveArrayTransition(); - ShapeImpl cachedShape = queryTransition(transition); - if (cachedShape != null) { - return cachedShape; - } - - ShapeImpl oldShape = (ShapeImpl) layout.getStrategy().ensureSpace(this, layout.getPrimitiveArrayLocation()); - ShapeImpl newShape = makeShapeWithPrimitiveExtensionArray(oldShape, transition); - oldShape.addDirectTransition(transition, newShape); - return newShape; - } - - /** - * Are these two shapes related, i.e. do they have the same root? - * - * @param other Shape to compare to - * @return true if one shape is an upcast of the other, or the Shapes are equal - */ - @Override - public boolean isRelated(Shape other) { - if (this == other) { - return true; - } - if (this.getRoot() == getRoot()) { - return true; - } - return false; - } - - /** - * Get a list of all properties that this Shape stores. - * - * @return list of properties - */ - @TruffleBoundary - @Override - public final List getPropertyList(Pred filter) { - LinkedList props = new LinkedList<>(); - next: for (Property currentProperty : this.propertyMap.reverseOrderValues()) { - if (!currentProperty.isHidden() && filter.test(currentProperty)) { - if (currentProperty.getLocation() instanceof DeclaredLocation) { - for (Iterator iter = props.iterator(); iter.hasNext();) { - Property other = iter.next(); - if (other.isShadow() && other.getKey().equals(currentProperty.getKey())) { - iter.remove(); - props.addFirst(other); - continue next; - } - } - } - props.addFirst(currentProperty); - } - } - return props; - } - - @Override - public final List getPropertyList() { - return getPropertyList(ALL); - } - - /** - * Returns all (also hidden) Property objects in this shape. - * - * @param ascending desired order - */ - @TruffleBoundary - @Override - public final List getPropertyListInternal(boolean ascending) { - LinkedList props = new LinkedList<>(); - for (Property current : this.propertyMap.reverseOrderValues()) { - if (ascending) { - props.addFirst(current); - } else { - props.add(current); - } - } - return props; - } - - /** - * Get a list of all (visible) property names in insertion order. - * - * @return list of property names - */ - @TruffleBoundary - @Override - public final List getKeyList(Pred filter) { - LinkedList keys = new LinkedList<>(); - for (Property currentProperty : this.propertyMap.reverseOrderValues()) { - if (!currentProperty.isHidden() && filter.test(currentProperty) && !currentProperty.isShadow()) { - keys.addFirst(currentProperty.getKey()); - } - } - return keys; - } - - @Override - public final List getKeyList() { - return getKeyList(ALL); - } - - @Override - public Iterable getKeys() { - return getKeyList(); - } - - @Override - public final boolean isValid() { - return getValidAssumption().isValid(); - } - - @Override - public final Assumption getValidAssumption() { - return validAssumption; - } - - private static Assumption createValidAssumption() { - return Truffle.getRuntime().createAssumption("valid shape"); - } - - public final void invalidateValidAssumption() { - getValidAssumption().invalidate(); - } - - @Override - public final boolean isLeaf() { - return leafAssumption == null || leafAssumption.isValid(); - } - - @Override - public final Assumption getLeafAssumption() { - if (leafAssumption == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - synchronized (getMutex()) { - if (leafAssumption == null) { - leafAssumption = isLeafHelper() ? createLeafAssumption() : NeverValidAssumption.INSTANCE; - } - } - } - return leafAssumption; - } - - private boolean isLeafHelper() { - return getTransitionMapForRead().isEmpty(); - } - - private static Assumption createLeafAssumption() { - return Truffle.getRuntime().createAssumption("leaf shape"); - } - - private void invalidateLeafAssumption() { - Assumption assumption = leafAssumption; - if (assumption != null) { - assumption.invalidate(); - } else { - leafAssumption = NeverValidAssumption.INSTANCE; - } - } - - @Override - public String toString() { - return toStringLimit(Integer.MAX_VALUE); - } - - @TruffleBoundary - public String toStringLimit(int limit) { - StringBuilder sb = new StringBuilder(); - sb.append('@'); - sb.append(Integer.toHexString(hashCode())); - if (!isValid()) { - sb.append('!'); - } - - sb.append("{"); - for (Iterator iterator = propertyMap.reverseOrderValues().iterator(); iterator.hasNext();) { - Property p = iterator.next(); - sb.append(p); - if (iterator.hasNext()) { - sb.append(", "); - } - if (sb.length() >= limit) { - sb.append("..."); - break; - } - sb.append("\n"); - } - sb.append("}"); - - return sb.toString(); - } - - @Override - public final ShapeImpl getParent() { - return parent; - } - - public final int getDepth() { - return depth; - } - - @Override - public final boolean hasProperty(Object name) { - return getProperty(name) != null; - } - - @TruffleBoundary - @Override - public final ShapeImpl removeProperty(Property prop) { - onPropertyTransition(prop); - - RemovePropertyTransition transition = new RemovePropertyTransition(prop); - ShapeImpl cachedShape = queryTransition(transition); - if (cachedShape != null) { - return cachedShape; - } - - ShapeImpl shape = getShapeFromProperty(prop.getKey()); - if (shape != null) { - List transitionList = new ArrayList<>(); - ShapeImpl current = this; - while (current != shape) { - if (!(current.getTransitionFromParent() instanceof Transition.DirectReplacePropertyTransition) || - !((Transition.DirectReplacePropertyTransition) current.getTransitionFromParent()).getPropertyBefore().getKey().equals(prop.getKey())) { - transitionList.add(current.getTransitionFromParent()); - } - current = current.parent; - } - ShapeImpl newShape = shape.parent; - for (ListIterator iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { - Transition previous = iterator.previous(); - newShape = newShape.applyTransition(previous, true); - } - - addIndirectTransition(transition, newShape); - return newShape; - } else { - return null; - } - } - - @TruffleBoundary - @Override - public final ShapeImpl append(Property oldProperty) { - return addProperty(oldProperty.relocate(allocator().moveLocation(oldProperty.getLocation()))); - } - - public final ShapeImpl applyTransition(Transition transition, boolean append) { - if (transition instanceof AddPropertyTransition) { - return append ? append(((AddPropertyTransition) transition).getProperty()) : addProperty(((AddPropertyTransition) transition).getProperty()); - } else if (transition instanceof ObjectTypeTransition) { - return changeType(((ObjectTypeTransition) transition).getObjectType()); - } else if (transition instanceof ReservePrimitiveArrayTransition) { - return reservePrimitiveExtensionArray(); - } else if (transition instanceof DirectReplacePropertyTransition) { - Property oldProperty = ((DirectReplacePropertyTransition) transition).getPropertyBefore(); - Property newProperty = ((DirectReplacePropertyTransition) transition).getPropertyAfter(); - if (append) { - assert oldProperty.getLocation() instanceof DualLocation && newProperty.getLocation() instanceof DualLocation; - oldProperty = getProperty(oldProperty.getKey()); - newProperty = newProperty.relocate(((DualLocation) oldProperty.getLocation()).changeType(((DualLocation) newProperty.getLocation()).getType())); - } - return replaceProperty(oldProperty, newProperty); - } else { - throw new UnsupportedOperationException(); - } - } - - @Override - public final BaseAllocator allocator() { - return layout.getStrategy().createAllocator(this); - } - - /** - * Duplicate shape exchanging existing property with new property. - */ - @Override - public ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { - return indirectReplaceProperty(oldProperty, newProperty); - } - - protected final ShapeImpl indirectReplaceProperty(Property oldProperty, Property newProperty) { - assert oldProperty.getKey().equals(newProperty.getKey()); - - Transition replacePropertyTransition = new Transition.IndirectReplacePropertyTransition(oldProperty, newProperty); - ShapeImpl cachedShape = queryTransition(replacePropertyTransition); - if (cachedShape != null) { - return cachedShape; - } - - ShapeImpl top = this; - List transitionList = new ArrayList<>(); - boolean found = false; - while (top != getRoot() && !found) { - Transition transition = top.getTransitionFromParent(); - transitionList.add(transition); - if (transition instanceof AddPropertyTransition && ((AddPropertyTransition) transition).getProperty().getKey().equals(newProperty.getKey())) { - found = true; - } - top = top.parent; - } - ShapeImpl newShape = top; - for (ListIterator iterator = transitionList.listIterator(transitionList.size()); iterator.hasPrevious();) { - Transition transition = iterator.previous(); - if (transition instanceof AddPropertyTransition && ((AddPropertyTransition) transition).getProperty().getKey().equals(newProperty.getKey())) { - newShape = newShape.addProperty(newProperty); - } else { - newShape = newShape.applyTransition(transition, false); - } - } - - addIndirectTransition(replacePropertyTransition, newShape); - return newShape; - } - - protected final ShapeImpl directReplaceProperty(Property oldProperty, Property newProperty) { - assert oldProperty.getKey().equals(newProperty.getKey()); - onPropertyTransition(oldProperty); - - Transition replacePropertyTransition = new Transition.DirectReplacePropertyTransition(oldProperty, newProperty); - ShapeImpl cachedShape = queryTransition(replacePropertyTransition); - if (cachedShape != null) { - return cachedShape; - } - PropertyMap newPropertyMap = this.getPropertyMap().replaceCopy(oldProperty, newProperty); - ShapeImpl newShape = createShape(getLayout(), getSharedData(), this, getObjectType(), newPropertyMap, replacePropertyTransition, allocator(), getId()); - - addDirectTransition(replacePropertyTransition, newShape); - return newShape; - } - - /** - * Find lowest common ancestor of two related shapes. - */ - public static ShapeImpl findCommonAncestor(ShapeImpl left, ShapeImpl right) { - if (!left.isRelated(right)) { - throw new IllegalArgumentException("shapes must have the same root"); - } else if (left == right) { - return left; - } - int leftLength = left.depth; - int rightLength = right.depth; - ShapeImpl leftPtr = left; - ShapeImpl rightPtr = right; - while (leftLength > rightLength) { - leftPtr = leftPtr.parent; - leftLength--; - } - while (rightLength > leftLength) { - rightPtr = rightPtr.parent; - rightLength--; - } - while (leftPtr != rightPtr) { - leftPtr = leftPtr.parent; - rightPtr = rightPtr.parent; - } - return leftPtr; - } - - @Override - public final int getPropertyCount() { - return propertyCount; - } - - /** - * Find difference between two shapes. - * - * @see ObjectStorageOptions#TraceReshape - */ - public static List diff(Shape oldShape, Shape newShape) { - List oldList = oldShape.getPropertyListInternal(false); - List newList = newShape.getPropertyListInternal(false); - - List diff = new ArrayList<>(oldList); - diff.addAll(newList); - List intersection = new ArrayList<>(oldList); - intersection.retainAll(newList); - diff.removeAll(intersection); - return diff; - } - - @Override - public ObjectType getObjectType() { - return objectType; - } - - @Override - public ShapeImpl getRoot() { - return root; - } - - @Override - public final boolean check(DynamicObject subject) { - return subject.getShape() == this; - } - - @Override - public final LayoutImpl getLayout() { - return layout; - } - - @Override - public final Object getData() { - return extraData; - } - - @Override - public final Object getSharedData() { - return sharedData; - } - - @TruffleBoundary - @Override - public final boolean hasTransitionWithKey(Object key) { - for (Transition transition : getTransitionMapForRead().keySet()) { - if (transition instanceof PropertyTransition) { - if (((PropertyTransition) transition).getProperty().getKey().equals(key)) { - return true; - } - } - } - return false; - } - - /** - * Clone off a separate shape with new shared data. - */ - @TruffleBoundary - @Override - public final ShapeImpl createSeparateShape(Object newSharedData) { - if (parent == null) { - return cloneRoot(this, newSharedData); - } else { - return this.cloneOnto(parent.createSeparateShape(newSharedData)); - } - } - - @Override - @TruffleBoundary - public final ShapeImpl changeType(ObjectType newOps) { - ObjectTypeTransition transition = new ObjectTypeTransition(newOps); - ShapeImpl cachedShape = queryTransition(transition); - if (cachedShape != null) { - return cachedShape; - } - - ShapeImpl newShape = createShape(layout, sharedData, this, newOps, propertyMap, transition, allocator(), id); - addDirectTransition(transition, newShape); - return newShape; - } - - @Override - public final ShapeImpl reservePrimitiveExtensionArray() { - if (layout.hasPrimitiveExtensionArray() && !hasPrimitiveArray()) { - return addPrimitiveExtensionArray(); - } - return this; - } - - @Override - public final Iterable getProperties() { - return getPropertyList(); - } - - @Override - public final DynamicObject newInstance() { - return layout.newInstance(this); - } - - @Override - public final DynamicObjectFactory createFactory() { - final List properties = getPropertyListInternal(true); - for (Iterator iterator = properties.iterator(); iterator.hasNext();) { - Property property = iterator.next(); - // skip non-instance fields - assert property.getLocation() != layout.getPrimitiveArrayLocation(); - if (property.getLocation() instanceof ValueLocation) { - iterator.remove(); - } - } - - return new DynamicObjectFactory() { - @CompilationFinal private final PropertyImpl[] instanceFields = properties.toArray(new PropertyImpl[properties.size()]); - - @ExplodeLoop - public DynamicObject newInstance(Object... initialValues) { - DynamicObject store = ShapeImpl.this.newInstance(); - for (int i = 0; i < instanceFields.length; i++) { - instanceFields[i].setInternal(store, initialValues[i]); - } - return store; - } - - public Shape getShape() { - return ShapeImpl.this; - } - }; - } - - @Override - public Object getMutex() { - return getRoot(); - } - - @Override - public Shape tryMerge(Shape other) { - return null; - } - - public abstract static class BaseAllocator extends Allocator implements LocationVisitor { - protected final LayoutImpl layout; - protected int objectArraySize; - protected int objectFieldSize; - protected int primitiveFieldSize; - protected int primitiveArraySize; - protected boolean hasPrimitiveArray; - protected int depth; - - protected BaseAllocator(LayoutImpl layout) { - this.layout = layout; - } - - protected BaseAllocator(ShapeImpl shape) { - this(shape.getLayout()); - this.objectArraySize = shape.objectArraySize; - this.objectFieldSize = shape.objectFieldSize; - this.primitiveFieldSize = shape.primitiveFieldSize; - this.primitiveArraySize = shape.primitiveArraySize; - this.hasPrimitiveArray = shape.hasPrimitiveArray; - this.depth = shape.depth; - } - - protected abstract Location moveLocation(Location oldLocation); - - protected abstract Location newObjectLocation(boolean useFinal, boolean nonNull); - - protected abstract Location newTypedObjectLocation(boolean useFinal, Class type, boolean nonNull); - - protected abstract Location newIntLocation(boolean useFinal); - - protected abstract Location newDoubleLocation(boolean useFinal); - - protected abstract Location newLongLocation(boolean useFinal); - - protected abstract Location newBooleanLocation(boolean useFinal); - - @Override - public final Location constantLocation(Object value) { - return new ConstantLocation(value); - } - - @Override - protected Location locationForValue(Object value, boolean useFinal, boolean nonNull) { - if (value instanceof Integer) { - return newIntLocation(useFinal); - } else if (value instanceof Double) { - return newDoubleLocation(useFinal); - } else if (value instanceof Long) { - return newLongLocation(useFinal); - } else if (value instanceof Boolean) { - return newBooleanLocation(useFinal); - } else if (ObjectStorageOptions.TypedObjectLocations && value != null) { - return newTypedObjectLocation(useFinal, value.getClass(), nonNull); - } - return newObjectLocation(useFinal, nonNull && value != null); - } - - protected abstract Location locationForValueUpcast(Object value, Location oldLocation); - - @Override - protected Location locationForType(Class type, boolean useFinal, boolean nonNull) { - if (type == int.class) { - return newIntLocation(useFinal); - } else if (type == double.class) { - return newDoubleLocation(useFinal); - } else if (type == long.class) { - return newLongLocation(useFinal); - } else if (type == boolean.class) { - return newBooleanLocation(useFinal); - } else if (ObjectStorageOptions.TypedObjectLocations && type != null && type != Object.class) { - assert !type.isPrimitive() : "unsupported primitive type"; - return newTypedObjectLocation(useFinal, type, nonNull); - } - return newObjectLocation(useFinal, nonNull); - } - - protected Location newDualLocation(Class type) { - return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, type); - } - - protected DualLocation newDualLocationForValue(Object value) { - Class initialType = null; - if (value instanceof Integer) { - initialType = int.class; - } else if (value instanceof Double) { - initialType = double.class; - } else if (value instanceof Boolean) { - initialType = boolean.class; - } else { - initialType = Object.class; - } - return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, initialType); - } - - protected Location newDeclaredDualLocation(Object value) { - return new DeclaredDualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), value, layout); - } - - protected T advance(T location0) { - if (location0 instanceof LocationImpl) { - LocationImpl location = (LocationImpl) location0; - if (location != layout.getPrimitiveArrayLocation()) { - location.accept(this); - } - if (layout.hasPrimitiveExtensionArray()) { - hasPrimitiveArray |= location == layout.getPrimitiveArrayLocation() || primitiveArraySize > 0; - } else { - assert !hasPrimitiveArray && primitiveArraySize == 0; - } - } - depth++; - return location0; - } - - @Override - public BaseAllocator addLocation(Location location) { - advance(location); - return this; - } - - public void visitObjectField(int index, int count) { - objectFieldSize = Math.max(objectFieldSize, index + count); - } - - public void visitObjectArray(int index, int count) { - objectArraySize = Math.max(objectArraySize, index + count); - } - - public void visitPrimitiveArray(int index, int count) { - primitiveArraySize = Math.max(primitiveArraySize, index + count); - } - - public void visitPrimitiveField(int index, int count) { - primitiveFieldSize = Math.max(primitiveFieldSize, index + count); - } - } - - private static void debugRegisterShape(ShapeImpl newShape) { - if (ObjectStorageOptions.DumpShapes) { - Debug.registerShape(newShape); - } - } - - /** - * Match all filter. - */ - private static final Pred ALL = new Pred() { - public boolean test(Property t) { - return true; - } - }; - - private static final DebugCounter shapeCount = DebugCounter.create("Shapes allocated total"); - private static final DebugCounter shapeCloneCount = DebugCounter.create("Shapes allocated cloned"); - private static final DebugCounter shapeCacheHitCount = DebugCounter.create("Shape cache hits"); - private static final DebugCounter shapeCacheMissCount = DebugCounter.create("Shape cache misses"); - - public ForeignAccess getForeignAccessFactory() { - return getObjectType().getForeignAccessFactory(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +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.object; - -import java.util.*; - -import com.oracle.truffle.api.object.*; - -public abstract class Transition { - @Override - public int hashCode() { - int result = 1; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - return true; - } - - public abstract boolean isDirect(); - - public abstract static class PropertyTransition extends Transition { - private final Property property; - - public PropertyTransition(Property property) { - this.property = property; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((property == null) ? 0 : property.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - PropertyTransition other = (PropertyTransition) obj; - if (!Objects.equals(property, other.property)) { - return false; - } - return true; - } - - public Property getProperty() { - return property; - } - } - - public static final class AddPropertyTransition extends PropertyTransition { - public AddPropertyTransition(Property property) { - super(property); - } - - @Override - public boolean isDirect() { - return true; - } - } - - public static final class RemovePropertyTransition extends PropertyTransition { - public RemovePropertyTransition(Property property) { - super(property); - } - - @Override - public boolean isDirect() { - return false; - } - } - - public static final class ObjectTypeTransition extends Transition { - private final ObjectType objectType; - - public ObjectTypeTransition(ObjectType objectType) { - this.objectType = objectType; - } - - public ObjectType getObjectType() { - return objectType; - } - - @Override - public boolean equals(Object other) { - return super.equals(other) && Objects.equals(objectType, ((ObjectTypeTransition) other).objectType); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((objectType == null) ? 0 : objectType.hashCode()); - return result; - } - - @Override - public boolean isDirect() { - return true; - } - } - - public abstract static class AbstractReplacePropertyTransition extends PropertyTransition { - private final Property after; - - public AbstractReplacePropertyTransition(Property before, Property after) { - super(before); - this.after = after; - } - - public Property getPropertyBefore() { - return this.getProperty(); - } - - public Property getPropertyAfter() { - return after; - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj) && this.after.equals(((AbstractReplacePropertyTransition) obj).after); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + after.hashCode(); - return result; - } - } - - public static final class IndirectReplacePropertyTransition extends AbstractReplacePropertyTransition { - public IndirectReplacePropertyTransition(Property before, Property after) { - super(before, after); - } - - @Override - public boolean isDirect() { - return false; - } - } - - public static final class DirectReplacePropertyTransition extends AbstractReplacePropertyTransition { - public DirectReplacePropertyTransition(Property before, Property after) { - super(before, after); - } - - @Override - public boolean isDirect() { - return true; - } - } - - public static final class ReservePrimitiveArrayTransition extends Transition { - public ReservePrimitiveArrayTransition() { - } - - @Override - public boolean isDirect() { - return true; - } - } - - public String getShortName() { - return this.getClass().getSimpleName().replaceFirst("Transition$", "").toLowerCase(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/GraphvizShapeVisitor.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/GraphvizShapeVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +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.object.debug; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; - -public class GraphvizShapeVisitor extends DebugShapeVisitor { - private final Set drawn; - private final StringBuilder sb = new StringBuilder(); - - public GraphvizShapeVisitor() { - this.drawn = new HashSet<>(); - } - - @Override - public GraphvizShapeVisitor visitShape(Shape shape, Map transitions) { - if (!drawn.add(shape)) { - return null; - } - - String prefix = "s"; - sb.append(prefix).append(getId(shape)); - sb.append(" [label=\""); - if (shape.getLastProperty() != null) { - sb.append(escapeString(shape.getLastProperty().toString())); - } else { - sb.append("ROOT"); - } - sb.append("\""); - sb.append(", shape=\"rectangle\""); - if (!shape.isValid()) { - sb.append(", color=\"red\", style=dotted"); - } - sb.append("];"); - - for (Entry entry : transitions.entrySet()) { - Shape dst = entry.getValue(); - dst.accept(this); - assert drawn.contains(dst); - - sb.append(prefix).append(getId(shape)).append("->").append(prefix).append(getId(dst)); - sb.append(" [label=\"").append(escapeString(entry.getKey().getShortName())).append("\"]"); - sb.append(";"); - } - - return this; - } - - private static String escapeString(String str) { - return str.replaceAll("\\\\", "\\\\").replaceAll("\"", "\\\\\""); - } - - @Override - public String toString() { - return new StringBuilder("digraph{").append(sb).append("}").toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/JSONShapeVisitor.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/JSONShapeVisitor.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +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.object.debug; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.api.utilities.JSONHelper.JSONArrayBuilder; -import com.oracle.truffle.api.utilities.JSONHelper.JSONObjectBuilder; -import com.oracle.truffle.object.*; -import com.oracle.truffle.object.Transition.PropertyTransition; - -public class JSONShapeVisitor extends DebugShapeVisitor { - @Override - public JSONObjectBuilder visitShape(Shape shape, Map transitions) { - JSONObjectBuilder sb = JSONHelper.object(); - JSONArrayBuilder transitionarray = JSONHelper.array(); - for (Entry entry : transitions.entrySet()) { - transitionarray.add(JSONHelper.object().add("transition", dumpTransition(entry.getKey())).add("successor", getId(entry.getValue()))); - } - JSONArrayBuilder propertiesarray = JSONHelper.array(); - for (Property p : shape.getPropertyList()) { - propertiesarray.add(dumpProperty(p)); - } - sb.add("id", getId(shape)); - sb.add("properties", propertiesarray); - sb.add("transitions", transitionarray); - sb.add("predecessor", shape.getParent() != null ? getId(shape.getParent()) : null); - sb.add("valid", shape.isValid()); - return sb; - } - - public JSONObjectBuilder dumpProperty(Property property) { - return JSONHelper.object().add("id", property.getKey().toString()).add("location", dumpLocation(property.getLocation())).add("flags", property.getFlags()); - } - - public JSONObjectBuilder dumpTransition(Transition transition) { - JSONObjectBuilder sb = JSONHelper.object().add("type", transition.getShortName()); - if (transition instanceof PropertyTransition) { - sb.add("property", dumpProperty(((PropertyTransition) transition).getProperty())); - } - return sb; - } - - public JSONObjectBuilder dumpLocation(Location location) { - JSONObjectBuilder obj = JSONHelper.object(); - obj.add("type", (location instanceof TypedLocation ? ((TypedLocation) location).getType() : Object.class).getName()); - // if (location instanceof Locations.FieldLocation) { - // obj.add("offset", ((Locations.FieldLocation) location).getOffset()); - // } - // if (location instanceof Locations.ArrayLocation) { - // obj.add("index", ((Locations.ArrayLocation) location).getIndex()); - // } - if (location instanceof Locations.ValueLocation) { - obj.add("value", String.valueOf(((Locations.ValueLocation) location).get(null, false))); - } - return obj; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/ShapeProfiler.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/ShapeProfiler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +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.object.debug; - -import java.io.*; -import java.text.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.object.*; - -public class ShapeProfiler { - private static final String LINE_SEPARATOR = "***********************************************"; - private static final String BULLET = "* "; - private static final String TOKEN_SEPARATOR = "\t"; - private final ConcurrentLinkedQueue queue; - - public ShapeProfiler() { - queue = new ConcurrentLinkedQueue<>(); - } - - public void track(DynamicObject obj) { - queue.add(obj); - } - - public void dump(PrintWriter out) { - ShapeStats globalStats = new ShapeStats("Cumulative results for all shapes"); - for (DynamicObject obj : queue) { - Shape shape = obj.getShape(); - globalStats.profile(shape); - } - - globalStats.dump(out); - } - - public void dump(PrintWriter out, int topResults) { - if (topResults > 0) { - IdentityHashMap shapeMap = new IdentityHashMap<>(); - - for (DynamicObject obj : queue) { - Shape shape = obj.getShape(); - ShapeStats stats = shapeMap.get(shape); - if (stats == null) { - shapeMap.put(shape, stats = new ShapeStats(createLabel(shape))); - } - stats.profile(shape); - } - - List allStats = new ArrayList<>(shapeMap.values()); - Collections.sort(allStats, new Comparator() { - public int compare(ShapeStats a, ShapeStats b) { - return Long.compare(b.jsObjects, a.jsObjects); - } - }); - - ShapeStats avgStats = new ShapeStats("Cumulative results for top " + topResults + " shapes"); - for (int i = 0; i < topResults; i++) { - ShapeStats stats = allStats.get(i); - stats.setLabel("Shape " + (i + 1) + ": " + stats.getLabel()); - stats.dump(out); - avgStats.add(stats); - } - avgStats.dump(out); - } - // Dump also cumulative results. - dump(out); - } - - private static String createLabel(Shape shape) { - String label = shape.toString(); - return label.substring(label.indexOf('{') + 1, label.lastIndexOf('}')); - } - - private static class ShapeStats { - private String label; - private long jsObjects; - private long oac; - private long oas; - private long ofs; - private long pac; - private long pas; - private long pfs; - - public ShapeStats(String label) { - this.label = label; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public void profile(Shape shape) { - jsObjects++; - oac += shape.getObjectArrayCapacity(); - oas += shape.getObjectArraySize(); - ofs += shape.getObjectFieldSize(); - pac += shape.getPrimitiveArrayCapacity(); - pas += shape.getPrimitiveArraySize(); - pfs += shape.getPrimitiveFieldSize(); - } - - public void add(ShapeStats stats) { - jsObjects += stats.jsObjects; - oac += stats.oac; - oas += stats.oas; - ofs += stats.ofs; - oac += stats.oac; - oas += stats.oas; - ofs += stats.ofs; - } - - public void dump(PrintWriter out) { - DecimalFormat format = new DecimalFormat("###.####"); - out.println(LINE_SEPARATOR); - out.println(BULLET + label); - out.println(LINE_SEPARATOR); - out.println(BULLET + "Allocated objects:\t" + jsObjects); - out.println(BULLET + "Total object array capacity:\t" + oac); - out.println(BULLET + "Total object array size:\t" + oas); - out.println(BULLET + "Total object field size:\t" + ofs); - out.println(BULLET + "Average object array capacity:\t" + avgOAC(format)); - out.println(BULLET + "Average object array size:\t" + avgOAS(format)); - out.println(BULLET + "Average object field size:\t" + avgOFS(format)); - out.println(LINE_SEPARATOR); - out.println(BULLET + "Total primitive array capacity:\t" + pac); - out.println(BULLET + "Total primitive array size:\t" + pas); - out.println(BULLET + "Total primitive field size:\t" + pfs); - out.println(BULLET + "Average primitive array capacity:\t" + avgPAC(format)); - out.println(BULLET + "Average primitive array size:\t" + avgPAS(format)); - out.println(BULLET + "Average primitive field size:\t" + avgPFS(format)); - out.println(LINE_SEPARATOR); - out.println(BULLET + toString()); - out.println(LINE_SEPARATOR + "\n"); - out.flush(); - } - - @Override - public String toString() { - DecimalFormat format = new DecimalFormat("###.####"); - // @formatter:off - return "{" + label + "}" + TOKEN_SEPARATOR - + jsObjects + TOKEN_SEPARATOR - + avgOAC(format) + TOKEN_SEPARATOR - + avgOAS(format) + TOKEN_SEPARATOR - + avgOFS(format) + TOKEN_SEPARATOR - + avgPAC(format) + TOKEN_SEPARATOR - + avgPAS(format) + TOKEN_SEPARATOR - + avgPFS(format); - // @formatter:on - } - - private String avgOAC(DecimalFormat format) { - return format.format((double) oac / jsObjects); - } - - private String avgOAS(DecimalFormat format) { - return format.format((double) oas / jsObjects); - } - - private String avgOFS(DecimalFormat format) { - return format.format((double) ofs / jsObjects); - } - - private String avgPAC(DecimalFormat format) { - return format.format((double) pac / jsObjects); - } - - private String avgPAS(DecimalFormat format) { - return format.format((double) pas / jsObjects); - } - - private String avgPFS(DecimalFormat format) { - return format.format((double) pfs / jsObjects); - } - } - - public static ShapeProfiler getInstance() { - return shapeProf; - } - - private static final ShapeProfiler shapeProf; - static { - if (ObjectStorageOptions.Profile) { - shapeProf = new ShapeProfiler(); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - getInstance().dump(new PrintWriter(System.out), ObjectStorageOptions.ProfileTopResults); - } - }); - } else { - shapeProf = null; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLSimpleTestSuite.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLSimpleTestSuite.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +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.sl.test; - -import org.junit.*; -import org.junit.runner.*; - -@RunWith(SLTestRunner.class) -@SLTestSuite({"graal/com.oracle.truffle.sl.test/tests", "tests"}) -public class SLSimpleTestSuite { - - public static void main(String[] args) throws Exception { - SLTestRunner.runInMain(SLSimpleTestSuite.class, args); - } - - /* - * Our "mx unittest" command looks for methods that are annotated with @Test. By just defining - * an empty method, this class gets included and the test suite is properly executed. - */ - @Test - public void unittest() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +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.sl.test; - -import com.oracle.truffle.tck.TruffleTCK; -import com.oracle.truffle.api.vm.TruffleVM; -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * This is the way to verify your language implementation is compatible. - * - */ -public class SLTckTest extends TruffleTCK { - @Test - public void testVerifyPresence() { - TruffleVM vm = TruffleVM.newVM().build(); - assertTrue("Our language is present", vm.getLanguages().containsKey("application/x-sl")); - } - - @Override - protected TruffleVM prepareVM() throws Exception { - TruffleVM vm = TruffleVM.newVM().build(); - // @formatter:off - vm.eval("application/x-sl", - "function fourtyTwo() {\n" + - " return 42;\n" + // - "}\n" + - "function plus(a, b) {\n" + - " return a + b;\n" + - "}\n" + - "function null() {\n" + - "}\n" - ); - // @formatter:on - return vm; - } - - @Override - protected String mimeType() { - return "application/x-sl"; - } - - @Override - protected String fourtyTwo() { - return "fourtyTwo"; - } - - @Override - protected String plusInt() { - return "plus"; - } - - @Override - protected String returnsNull() { - return "null"; - } - - @Override - protected String invalidCode() { - // @formatter:off - return - "f unction main() {\n" + - " retu rn 42;\n" + - "}\n"; - // @formatter:on - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.test; - -import java.io.*; -import java.nio.charset.*; -import java.nio.file.*; -import java.nio.file.attribute.*; -import java.util.*; - -import org.junit.*; -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.manipulation.*; -import org.junit.runner.notification.*; -import org.junit.runners.*; -import org.junit.runners.model.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.vm.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.builtins.*; -import com.oracle.truffle.sl.test.SLTestRunner.TestCase; - -public final class SLTestRunner extends ParentRunner { - - private static int repeats = 1; - - private static final String SOURCE_SUFFIX = ".sl"; - private static final String INPUT_SUFFIX = ".input"; - private static final String OUTPUT_SUFFIX = ".output"; - - private static final String LF = System.getProperty("line.separator"); - - static class TestCase { - protected final Description name; - protected final Path path; - protected final String sourceName; - protected final String testInput; - protected final String expectedOutput; - protected String actualOutput; - - protected TestCase(Class testClass, String baseName, String sourceName, Path path, String testInput, String expectedOutput) { - this.name = Description.createTestDescription(testClass, baseName); - this.sourceName = sourceName; - this.path = path; - this.testInput = testInput; - this.expectedOutput = expectedOutput; - } - } - - private final List testCases; - - public SLTestRunner(Class runningClass) throws InitializationError { - super(runningClass); - try { - testCases = createTests(runningClass); - } catch (IOException e) { - throw new InitializationError(e); - } - } - - @Override - protected Description describeChild(TestCase child) { - return child.name; - } - - @Override - protected List getChildren() { - return testCases; - } - - protected static List createTests(final Class c) throws IOException, InitializationError { - SLTestSuite suite = c.getAnnotation(SLTestSuite.class); - if (suite == null) { - throw new InitializationError(String.format("@%s annotation required on class '%s' to run with '%s'.", SLTestSuite.class.getSimpleName(), c.getName(), SLTestRunner.class.getSimpleName())); - } - - String[] pathes = suite.value(); - - Path root = null; - for (String path : pathes) { - root = FileSystems.getDefault().getPath(path); - if (Files.exists(root)) { - break; - } - } - if (root == null && pathes.length > 0) { - throw new FileNotFoundException(pathes[0]); - } - - final Path rootPath = root; - - final List foundCases = new ArrayList<>(); - Files.walkFileTree(rootPath, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { - String sourceName = sourceFile.getFileName().toString(); - if (sourceName.endsWith(SOURCE_SUFFIX)) { - String baseName = sourceName.substring(0, sourceName.length() - SOURCE_SUFFIX.length()); - - Path inputFile = sourceFile.resolveSibling(baseName + INPUT_SUFFIX); - String testInput = ""; - if (Files.exists(inputFile)) { - testInput = readAllLines(inputFile); - } - - Path outputFile = sourceFile.resolveSibling(baseName + OUTPUT_SUFFIX); - String expectedOutput = ""; - if (Files.exists(outputFile)) { - expectedOutput = readAllLines(outputFile); - } - - foundCases.add(new TestCase(c, baseName, sourceName, sourceFile, testInput, expectedOutput)); - } - return FileVisitResult.CONTINUE; - } - }); - return foundCases; - } - - private static String readAllLines(Path file) throws IOException { - // fix line feeds for non unix os - StringBuilder outFile = new StringBuilder(); - for (String line : Files.readAllLines(file, Charset.defaultCharset())) { - outFile.append(line).append(LF); - } - return outFile.toString(); - } - - public static void setRepeats(int repeats) { - SLTestRunner.repeats = repeats; - } - - private static final List> builtins = new ArrayList<>(); - - public static void installBuiltin(NodeFactory builtin) { - builtins.add(builtin); - } - - @Override - protected void runChild(TestCase testCase, RunNotifier notifier) { - notifier.fireTestStarted(testCase.name); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintWriter printer = new PrintWriter(out); - try { - TruffleVM vm = TruffleVM.newVM().stdIn(new BufferedReader(new StringReader(repeat(testCase.testInput, repeats)))).stdOut(printer).build(); - - String script = readAllLines(testCase.path); - SLLanguage.run(vm, testCase.path.toUri(), null, printer, repeats, builtins); - - printer.flush(); - String actualOutput = new String(out.toByteArray()); - Assert.assertEquals(script, repeat(testCase.expectedOutput, repeats), actualOutput); - } catch (Throwable ex) { - notifier.fireTestFailure(new Failure(testCase.name, new IllegalStateException("Cannot run " + testCase.sourceName, ex))); - } finally { - notifier.fireTestFinished(testCase.name); - } - } - - private static String repeat(String s, int count) { - StringBuilder result = new StringBuilder(s.length() * count); - for (int i = 0; i < count; i++) { - result.append(s); - } - return result.toString(); - } - - public static void runInMain(Class testClass, String[] args) throws InitializationError, NoTestsRemainException { - JUnitCore core = new JUnitCore(); - core.addListener(new TextListener(System.out)); - SLTestRunner suite = new SLTestRunner(testClass); - if (args.length > 0) { - suite.filter(new NameFilter(args[0])); - } - Result r = core.run(suite); - if (!r.wasSuccessful()) { - System.exit(1); - } - } - - private static final class NameFilter extends Filter { - private final String pattern; - - private NameFilter(String pattern) { - this.pattern = pattern.toLowerCase(); - } - - @Override - public boolean shouldRun(Description description) { - return description.getMethodName().toLowerCase().contains(pattern); - } - - @Override - public String describe() { - return "Filter contains " + pattern; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestSuite.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestSuite.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +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.sl.test; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface SLTestSuite { - - /** - * Defines the base path of the test suite. Multiple base pathes can be specified. However only - * the first base that exists is used to lookup the test cases. - */ - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +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.sl.test.instrument; - -import java.io.*; -import java.nio.charset.*; -import java.nio.file.*; -import java.nio.file.attribute.*; -import java.util.*; - -import org.junit.*; -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.manipulation.*; -import org.junit.runner.notification.*; -import org.junit.runners.*; -import org.junit.runners.model.*; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.factory.*; -import com.oracle.truffle.sl.nodes.instrument.*; -import com.oracle.truffle.sl.nodes.local.*; -import com.oracle.truffle.sl.parser.*; -import com.oracle.truffle.sl.runtime.*; -import com.oracle.truffle.sl.test.instrument.SLInstrumentTestRunner.InstrumentTestCase; - -/** - * This class builds and executes the tests for instrumenting SL. Although much of this class is - * written with future automation in mind, at the moment the tests that are created are hard-coded - * according to the file name of the test. To be automated, an automatic way of generating both the - * node visitor and the node prober is necessary. - * - * Testing is done via JUnit via comparing execution outputs with expected outputs. - */ -public final class SLInstrumentTestRunner extends ParentRunner { - - private static final String SOURCE_SUFFIX = ".sl"; - private static final String INPUT_SUFFIX = ".input"; - private static final String OUTPUT_SUFFIX = ".output"; - private static final String ASSIGNMENT_VALUE_SUFFIX = "_assnCount"; - - private static final String LF = System.getProperty("line.separator"); - private static SLContext slContext; - - static class InstrumentTestCase { - protected final Description name; - protected final Path path; - protected final String baseName; - protected final String sourceName; - protected final String testInput; - protected final String expectedOutput; - protected String actualOutput; - - protected InstrumentTestCase(Class testClass, String baseName, String sourceName, Path path, String testInput, String expectedOutput) { - this.name = Description.createTestDescription(testClass, baseName); - this.baseName = baseName; - this.sourceName = sourceName; - this.path = path; - this.testInput = testInput; - this.expectedOutput = expectedOutput; - } - } - - private final List testCases; - - public SLInstrumentTestRunner(Class testClass) throws InitializationError { - super(testClass); - final SLStandardASTProber prober = new SLStandardASTProber(); - Probe.registerASTProber(prober); - try { - testCases = createTests(testClass); - } catch (IOException e) { - throw new InitializationError(e); - } finally { - Probe.unregisterASTProber(prober); - } - } - - @Override - protected List getChildren() { - return testCases; - } - - @Override - protected Description describeChild(InstrumentTestCase child) { - return child.name; - } - - /** - * Tests are created based on the files that exist in the directory specified in the passed in - * annotation. Each test must have a source file and an expected output file. Optionally, each - * test can also include an input file. Source files have an ".sl" extension. Expected output - * have a ".output" extension. Input files have an ".input" extension. All these files must - * share the same base name to be correctly grouped. For example: "test1_assnCount.sl", - * "test1_assnCount.output" and "test1_assnCount.input" would all be used to create a single - * test called "test1_assnCount". - * - * This method iterates over the files in the directory and creates a new InstrumentTestCase for - * each group of related files. Each file is also expected to end with an identified at the end - * of the base name to indicate what visitor needs to be attached. Currently, visitors are hard - * coded to work on specific lines, so the code here is not currently generalizable. - * - * @param c The annotation containing the directory with tests - * @return A list of {@link InstrumentTestCase}s to run. - * @throws IOException If the directory is invalid. - * @throws InitializationError If no directory is provided. - * - * @see #runChild(InstrumentTestCase, RunNotifier) - */ - protected static List createTests(final Class c) throws IOException, InitializationError { - SLInstrumentTestSuite suite = c.getAnnotation(SLInstrumentTestSuite.class); - if (suite == null) { - throw new InitializationError(String.format("@%s annotation required on class '%s' to run with '%s'.", SLInstrumentTestSuite.class.getSimpleName(), c.getName(), - SLInstrumentTestRunner.class.getSimpleName())); - } - - String[] paths = suite.value(); - - Path root = null; - for (String path : paths) { - root = FileSystems.getDefault().getPath(path); - if (Files.exists(root)) { - break; - } - } - if (root == null && paths.length > 0) { - throw new FileNotFoundException(paths[0]); - } - - final Path rootPath = root; - - final List testCases = new ArrayList<>(); - - // Scaffolding in place for future automation - Files.walkFileTree(rootPath, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { - String sourceName = sourceFile.getFileName().toString(); - if (sourceName.endsWith(SOURCE_SUFFIX)) { - String baseName = sourceName.substring(0, sourceName.length() - SOURCE_SUFFIX.length()); - - Path inputFile = sourceFile.resolveSibling(baseName + INPUT_SUFFIX); - String testInput = ""; - if (Files.exists(inputFile)) { - testInput = readAllLines(inputFile); - } - - Path outputFile = sourceFile.resolveSibling(baseName + OUTPUT_SUFFIX); - String expectedOutput = ""; - if (Files.exists(outputFile)) { - expectedOutput = readAllLines(outputFile); - } - - testCases.add(new InstrumentTestCase(c, baseName, sourceName, sourceFile, testInput, expectedOutput)); - - } - return FileVisitResult.CONTINUE; - } - }); - - return testCases; - } - - private static String readAllLines(Path file) throws IOException { - // fix line feeds for non unix os - StringBuilder outFile = new StringBuilder(); - for (String line : Files.readAllLines(file, Charset.defaultCharset())) { - outFile.append(line).append(LF); - } - return outFile.toString(); - } - - /** - * Executes the passed in test case. Instrumentation is added according to the name of the file - * as explained in {@link #createTests(Class)}. Note that this code is not generalizable. - */ - @Override - protected void runChild(InstrumentTestCase testCase, RunNotifier notifier) { - // TODO Current tests are hard-coded, automate this eventually - notifier.fireTestStarted(testCase.name); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintWriter printer = new PrintWriter(out); - final ASTProber prober = new SLStandardASTProber(); - Probe.registerASTProber(prober); - try { - // We use the name of the file to determine what visitor to attach to it. - if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) { - // Set up the execution context for Simple and register our two listeners - slContext = SLContextFactory.create(new BufferedReader(new StringReader(testCase.testInput)), printer); - - final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName); - Parser.parseSL(slContext, source); - - // Attach an instrument to every probe tagged as an assignment - for (Probe probe : Probe.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) { - SLPrintAssigmentValueListener slPrintAssigmentValueListener = new SLPrintAssigmentValueListener(printer); - probe.attach(Instrument.create(slPrintAssigmentValueListener, "SL print assignment value")); - } - - SLFunction main = slContext.getFunctionRegistry().lookup("main"); - main.getCallTarget().call(); - } else { - notifier.fireTestFailure(new Failure(testCase.name, new UnsupportedOperationException("No instrumentation found."))); - } - - printer.flush(); - String actualOutput = new String(out.toByteArray()); - Assert.assertEquals(testCase.expectedOutput, actualOutput); - } catch (Throwable ex) { - notifier.fireTestFailure(new Failure(testCase.name, ex)); - } finally { - Probe.unregisterASTProber(prober); - notifier.fireTestFinished(testCase.name); - } - - } - - public static void runInMain(Class testClass, String[] args) throws InitializationError, NoTestsRemainException { - JUnitCore core = new JUnitCore(); - core.addListener(new TextListener(System.out)); - SLInstrumentTestRunner suite = new SLInstrumentTestRunner(testClass); - if (args.length > 0) { - suite.filter(new NameFilter(args[0])); - } - Result r = core.run(suite); - if (!r.wasSuccessful()) { - System.exit(1); - } - } - - private static final class NameFilter extends Filter { - private final String pattern; - - private NameFilter(String pattern) { - this.pattern = pattern.toLowerCase(); - } - - @Override - public boolean shouldRun(Description description) { - return description.getMethodName().toLowerCase().contains(pattern); - } - - @Override - public String describe() { - return "Filter contains " + pattern; - } - } - - /** - * This sample listener provides prints the value of an assignment (after the assignment is - * complete) to the {@link PrintWriter} specified in the constructor. This listener can only be - * attached at {@link SLWriteLocalVariableNode}, but provides no guards to protect it from being - * attached elsewhere. - */ - public final class SLPrintAssigmentValueListener extends DefaultSimpleInstrumentListener { - - private PrintWriter output; - - public SLPrintAssigmentValueListener(PrintWriter output) { - this.output = output; - } - - @Override - public void returnValue(Probe probe, Object result) { - output.println(result); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestSuite.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestSuite.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +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.sl.test.instrument; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface SLInstrumentTestSuite { - - /** - * Defines the base path of the test suite. Multiple base paths can be specified. However only - * the first base that exists is used to lookup the test cases. - */ - String[] value(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLSimpleInstrumentTestSuite.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLSimpleInstrumentTestSuite.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +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.sl.test.instrument; - -import org.junit.*; -import org.junit.runner.*; - -@RunWith(SLInstrumentTestRunner.class) -@SLInstrumentTestSuite({"graal/com.oracle.truffle.sl.test/tests_instrumentation", "tests_instrumentation"}) -public class SLSimpleInstrumentTestSuite { - - public static void main(String[] args) throws Exception { - SLInstrumentTestRunner.runInMain(SLSimpleInstrumentTestSuite.class, args); - } - - /* - * Our "mx unittest" command looks for methods that are annotated with @Test. By just defining - * an empty method, this class gets included and the test suite is properly executed. - */ - @Test - public void unittest() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Add.output --- a/graal/com.oracle.truffle.sl.test/tests/Add.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -7 -34 -34 -34 -4000000000003 -3000000000004 -7000000000000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Add.sl --- a/graal/com.oracle.truffle.sl.test/tests/Add.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -function main() { - println(3 + 4); - println(3 + "4"); - println("3" + 4); - println("3" + "4"); - println(3 + 4000000000000); - println(3000000000000 + 4); - println(3000000000000 + 4000000000000); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Arithmetic.output --- a/graal/com.oracle.truffle.sl.test/tests/Arithmetic.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -5 -1 --3 -14 -11 -5 --3 -1 -18 -11 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Arithmetic.sl --- a/graal/com.oracle.truffle.sl.test/tests/Arithmetic.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -function main() { - println(3 + 4 - 2); - println(3 - 4 + 2); - println(3 - 4 - 2); - println(3 * 4 + 2); - println(3 + 4 * 2); - println(3 + (4 - 2)); - println(3 - (4 + 2)); - println(3 - (4 - 2)); - println(3 * (4 + 2)); - println(3 + (4 * 2)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Break.output --- a/graal/com.oracle.truffle.sl.test/tests/Break.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -942 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Break.sl --- a/graal/com.oracle.truffle.sl.test/tests/Break.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -function main() { - i = 0; - while (i < 1000) { - if (i >= 942) { - break; - } - i = i + 1; - } - return i; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Builtins.output --- a/graal/com.oracle.truffle.sl.test/tests/Builtins.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Hello World! diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Builtins.sl --- a/graal/com.oracle.truffle.sl.test/tests/Builtins.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -function main() { - println("Hello World!"); - nanoTime(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/CalcShell.input --- a/graal/com.oracle.truffle.sl.test/tests/CalcShell.input Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -i -80 -c -return cur + i; -r -c -if (i <= 2) { return 1; } else { return prev + cur; } -r -i -100 -r -c -if (i == 0) { return 1; } else { return cur * i; } -r -x diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/CalcShell.output --- a/graal/com.oracle.truffle.sl.test/tests/CalcShell.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -available commands: -x: exit -c: define the calculation function with the parameters prev, cur, and i - prev and cur start with 0; i is the loop variable from 0 to n - example: 'return cur + i;' computes the sum of 1 to n - example: 'if (i == 0) { return 1; } else { return cur * i; }' computes the factorial of i - example: 'if (i <= 2) { return 1; } else { return prev + cur; }' computes the nth Fibonacci number -i: define the number of iterations, i.e, the number n in the examples above -r: Run the calculation loop often, and print the first and last result -t: Run the calculation loop a couple of time, and print timing information for each run -h: Print this help message - -cmd> -n> -cmd> -function> -cmd> -** first: 3240 -** last: 3240 -cmd> -function> -cmd> -** first: 23416728348467685 -** last: 23416728348467685 -cmd> -n> -cmd> -** first: 354224848179261915075 -** last: 354224848179261915075 -cmd> -function> -cmd> -** first: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 -** last: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 -cmd> diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/CalcShell.sl --- a/graal/com.oracle.truffle.sl.test/tests/CalcShell.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -function iterations() { - return 80; -} - -function calcLoop(n) { - i = 0; - prev = cur = 0; - while (i <= n) { - next = calc(prev, cur, i); - prev = cur; - cur = next; - i = i + 1; - } - return cur; -} - -function timing(n) { - i = 0; - while (i < 20) { - start = nanoTime(); - calcLoop(n); - end = nanoTime(); - i = i + 1; - - println("** run " + i + ": " + (end - start) + " ns"); - } -} - -function run(n) { - firstResult = calcLoop(n); - println("** first: " + firstResult); - i = 0; - while (i < 100) { - calcLoop(n); - i = i + 1; - } - lastResult = calcLoop(n); - println("** last: " + lastResult); - - if (firstResult != lastResult) { - println("ERROR: result not stable"); - } -} - -function help() { - println("available commands:"); - println("x: exit"); - println("c: define the calculation function with the parameters prev, cur, and i"); - println(" prev and cur start with 0; i is the loop variable from 0 to n"); - println(" example: 'return cur + i;' computes the sum of 1 to n"); - println(" example: 'if (i == 0) { return 1; } else { return cur * i; }' computes the factorial of i"); - println(" example: 'if (i <= 2) { return 1; } else { return prev + cur; }' computes the nth Fibonacci number"); - println("i: define the number of iterations, i.e, the number n in the examples above"); - println("r: Run the calculation loop often, and print the first and last result"); - println("t: Run the calculation loop a couple of time, and print timing information for each run"); - println("h: Print this help message"); - println(""); -} - -function main() { - help(); - - while (1 == 1) { - println("cmd>"); - cmd = readln(); - if (cmd == "x" || cmd == "") { - return; - } - if (cmd == "h") { - help(); - } - if (cmd == "c") { - println("function>"); - code = readln(); - defineFunction("function calc(prev, cur, i) { " + code + "}"); - } - if (cmd == "t") { - timing(iterations()); - } - if (cmd == "r") { - run(iterations()); - } - if (cmd == "i") { - println("n>"); - n = readln(); - defineFunction("function iterations() { return " + n + "; }"); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Call.output --- a/graal/com.oracle.truffle.sl.test/tests/Call.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -42 -42 -42 -42 -42 -42 -42 -42 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Call.sl --- a/graal/com.oracle.truffle.sl.test/tests/Call.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -function ret(a) { return a; } -function dub(a) { return a * 2; } -function inc(a) { return a + 1; } -function dec(a) { return a - 1; } -function call(f, v) { return f(v); } - -function main() { - println(ret(42)); - println(dub(21)); - println(inc(41)); - println(dec(43)); - println(call(ret, 42)); - println(call(dub, 21)); - println(call(inc, 41)); - println(call(dec, 43)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Comparison.output --- a/graal/com.oracle.truffle.sl.test/tests/Comparison.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -< -true -false -false -true -false -true -false -false -<= -true -false -true -true -false -true -false -true -> -false -true -false -false -true -false -true -false ->= -false -true -true -false -true -false -true -true -== -false -false -true -false -false -false -false -true -!= -true -true -false -true -true -true -true -false diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Comparison.sl --- a/graal/com.oracle.truffle.sl.test/tests/Comparison.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -function main() { - println("<"); - println(4 < 20); - println(40 < 2); - println(4 < 4); - println(4 < 200000000000000000000000000); - println(40000000000000000000000000 < 20); - println(40000000000000000000000000 < 200000000000000000000000000); - println(400000000000000000000000000 < 20000000000000000000000000); - println(40000000000000000000000000 < 40000000000000000000000000); - - println("<="); - println(4 <= 20); - println(40 <= 2); - println(4 <= 4); - println(4 <= 200000000000000000000000000); - println(40000000000000000000000000 <= 20); - println(40000000000000000000000000 <= 200000000000000000000000000); - println(400000000000000000000000000 <= 20000000000000000000000000); - println(40000000000000000000000000 <= 40000000000000000000000000); - - println(">"); - println(4 > 20); - println(40 > 2); - println(4 > 4); - println(4 > 200000000000000000000000000); - println(40000000000000000000000000 > 20); - println(40000000000000000000000000 > 200000000000000000000000000); - println(400000000000000000000000000 > 20000000000000000000000000); - println(40000000000000000000000000 > 40000000000000000000000000); - - println(">="); - println(4 >= 20); - println(40 >= 2); - println(4 >= 4); - println(4 >= 200000000000000000000000000); - println(40000000000000000000000000 >= 20); - println(40000000000000000000000000 >= 200000000000000000000000000); - println(400000000000000000000000000 >= 20000000000000000000000000); - println(40000000000000000000000000 >= 40000000000000000000000000); - - println("=="); - println(4 == 20); - println(40 == 2); - println(4 == 4); - println(4 == 200000000000000000000000000); - println(40000000000000000000000000 == 20); - println(40000000000000000000000000 == 200000000000000000000000000); - println(400000000000000000000000000 == 20000000000000000000000000); - println(40000000000000000000000000 == 40000000000000000000000000); - - println("!="); - println(4 != 20); - println(40 != 2); - println(4 != 4); - println(4 != 200000000000000000000000000); - println(40000000000000000000000000 != 20); - println(40000000000000000000000000 != 200000000000000000000000000); - println(400000000000000000000000000 != 20000000000000000000000000); - println(40000000000000000000000000 != 40000000000000000000000000); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/ControlFlow.output --- a/graal/com.oracle.truffle.sl.test/tests/ControlFlow.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/ControlFlow.sl --- a/graal/com.oracle.truffle.sl.test/tests/ControlFlow.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -function foo() {} -function bar() {} - -function main() { - foo(); - if (1 < 2) { - bar(); - return 1; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/DefineFunction.output --- a/graal/com.oracle.truffle.sl.test/tests/DefineFunction.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -42 -38 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/DefineFunction.sl --- a/graal/com.oracle.truffle.sl.test/tests/DefineFunction.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -function foo() { - println(test(40, 2)); -} - -function main() { - defineFunction("function test(a, b) { return a + b; }"); - foo(); - - defineFunction("function test(a, b) { return a - b; }"); - foo(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Div.output --- a/graal/com.oracle.truffle.sl.test/tests/Div.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -2 -0 -1000000000000 -1 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Div.sl --- a/graal/com.oracle.truffle.sl.test/tests/Div.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -function main() { - println(4 / 2); - println(4 / 4000000000000); - println(3000000000000 / 3); - println(3000000000000 / 3000000000000); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Fibonacci.output --- a/graal/com.oracle.truffle.sl.test/tests/Fibonacci.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -1: 1 -2: 1 -3: 2 -4: 3 -5: 5 -6: 8 -7: 13 -8: 21 -9: 34 -10: 55 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Fibonacci.sl --- a/graal/com.oracle.truffle.sl.test/tests/Fibonacci.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -function fib(num) { - if (num < 1) {return 0;} - n1 = 0; - n2 = 1; - i = 1; - while (i < num) { - next = n2 + n1; - n1 = n2; - n2 = next; - i = i + 1; - } - return n2; -} - -function main() { - i = 1; - while (i <= 10) { - println(i + ": " + fib(i)); - i = i + 1; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.output --- a/graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -42 -38 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.sl --- a/graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -function add(a, b) { - return a + b; -} - -function sub(a, b) { - return a - b; -} - -function foo(f) { - println(f(40, 2)); -} - -function main() { - foo(add); - foo(sub); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output --- a/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -Initial stack trace: -Frame: root doIt, a=0, hello=null -Frame: root main, i=0 -After 123 assignment: -Frame: root doIt, a=0, hello=123 -Frame: root main, i=0 -After hello assignment: -Frame: root doIt, a=0, hello=world -Frame: root main, i=0 -Initial stack trace: -Frame: root doIt, a=1, hello=null -Frame: root main, i=1 -After 123 assignment: -Frame: root doIt, a=1, hello=123 -Frame: root main, i=1 -After hello assignment: -Frame: root doIt, a=1, hello=world -Frame: root main, i=1 -Initial stack trace: -Frame: root doIt, a=2, hello=null -Frame: root main, i=2 -After 123 assignment: -Frame: root doIt, a=2, hello=123 -Frame: root main, i=2 -After hello assignment: -Frame: root doIt, a=2, hello=world -Frame: root main, i=2 -Initial stack trace: -Frame: root doIt, a=3, hello=null -Frame: root main, i=3 -After 123 assignment: -Frame: root doIt, a=3, hello=123 -Frame: root main, i=3 -After hello assignment: -Frame: root doIt, a=3, hello=world -Frame: root main, i=3 -Initial stack trace: -Frame: root doIt, a=4, hello=null -Frame: root main, i=4 -After 123 assignment: -Frame: root doIt, a=4, hello=123 -Frame: root main, i=4 -After hello assignment: -Frame: root doIt, a=4, hello=world -Frame: root main, i=4 -Initial stack trace: -Frame: root doIt, a=5, hello=null -Frame: root main, i=5 -After 123 assignment: -Frame: root doIt, a=5, hello=123 -Frame: root main, i=5 -After hello assignment: -Frame: root doIt, a=5, hello=world -Frame: root main, i=5 -Initial stack trace: -Frame: root doIt, a=6, hello=null -Frame: root main, i=6 -After 123 assignment: -Frame: root doIt, a=6, hello=123 -Frame: root main, i=6 -After hello assignment: -Frame: root doIt, a=6, hello=world -Frame: root main, i=6 -Initial stack trace: -Frame: root doIt, a=7, hello=null -Frame: root main, i=7 -After 123 assignment: -Frame: root doIt, a=7, hello=123 -Frame: root main, i=7 -After hello assignment: -Frame: root doIt, a=7, hello=world -Frame: root main, i=7 -Initial stack trace: -Frame: root doIt, a=8, hello=null -Frame: root main, i=8 -After 123 assignment: -Frame: root doIt, a=8, hello=123 -Frame: root main, i=8 -After hello assignment: -Frame: root doIt, a=8, hello=world -Frame: root main, i=8 -Initial stack trace: -Frame: root doIt, a=9, hello=null -Frame: root main, i=9 -After 123 assignment: -Frame: root doIt, a=9, hello=123 -Frame: root main, i=9 -After hello assignment: -Frame: root doIt, a=9, hello=world -Frame: root main, i=9 \ No newline at end of file diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl --- a/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -function doIt(a) { - println("Initial stack trace:"); - println(stacktrace()); - - hello = 123; - println("After 123 assignment:"); - println(stacktrace()); - - helloEqualsWorld(); - println("After hello assignment:"); - println(stacktrace()); - -// readln(); -} - -function main() { - i = 0; - while (i < 10) { - doIt(i); - i = i + 1; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/HelloWorld.output --- a/graal/com.oracle.truffle.sl.test/tests/HelloWorld.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Hello World! diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/HelloWorld.sl --- a/graal/com.oracle.truffle.sl.test/tests/HelloWorld.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - println("Hello World!"); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Inlining.output --- a/graal/com.oracle.truffle.sl.test/tests/Inlining.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1260000 \ No newline at end of file diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Inlining.sl --- a/graal/com.oracle.truffle.sl.test/tests/Inlining.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ - -function a() {return 42;} -function b() {return a();} -function c() {return b();} -function d() {return c();} -function e() {return c();} -function f() {return c();} -function g() {return d() + e() + f();} - -function main() { - i = 0; - result = 0; - while (i < 10000) { - result = result + g(); - i = i + 1; - } - return result; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Loop.output --- a/graal/com.oracle.truffle.sl.test/tests/Loop.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Loop.sl --- a/graal/com.oracle.truffle.sl.test/tests/Loop.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -function main() { - i = 0; - while (i < 1000) { - i = i + 1; - } - return i; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopCall.output --- a/graal/com.oracle.truffle.sl.test/tests/LoopCall.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopCall.sl --- a/graal/com.oracle.truffle.sl.test/tests/LoopCall.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -function add(a, b) { - return a + b; -} - -function loop(n) { - i = 0; - while (i < n) { - i = add(i, 1); - } - return i; -} - -function main() { - i = 0; - while (i < 20) { - loop(1000); - i = i + 1; - } - println(loop(1000)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output --- a/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl --- a/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -function add(a, b) { - return a + b; -} - -function loop(n) { - i = 0; - while (i < n) { - i = add(i, 1); - } - return i; -} - -function main() { - i = 0; - while (i < 20) { - loop(1000); - i = i + 1; - } - add("a", "b"); - println(loop(1000)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.output --- a/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl --- a/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -function add(a, b) { - return a + b; -} - -function loop(n) { - i = 0; - while (i < n) { - i = add(i, 1); - } - return i; -} - -function main() { - add("a", "b"); - - i = 0; - while (i < 20) { - loop(1000); - i = i + 1; - } - println(loop(1000)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopPrint.output --- a/graal/com.oracle.truffle.sl.test/tests/LoopPrint.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -1000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl --- a/graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -function loop(n) { - i = 0; - while (i < n) { - i = i + 1; - } - return i; -} - -function main() { - i = 0; - while (i < 20) { - loop(1000); - i = i + 1; - } - println(loop(1000)); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Mul.output --- a/graal/com.oracle.truffle.sl.test/tests/Mul.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -12 -12000000000000 -12000000000000 -12000000000000000000000000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Mul.sl --- a/graal/com.oracle.truffle.sl.test/tests/Mul.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -function main() { - println(3 * 4); - println(3 * 4000000000000); - println(3000000000000 * 4); - println(3000000000000 * 4000000000000); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Null.output --- a/graal/com.oracle.truffle.sl.test/tests/Null.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -null -true -false -false -true -false -true diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Null.sl --- a/graal/com.oracle.truffle.sl.test/tests/Null.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -/* The easiest way to generate null: a function without a return statement implicitly returns null. */ -function null() { -} - -function main() { - println(null()); - println(null() == null()); - println(null() != null()); - println(null() == 42); - println(null() != 42); - println(null() == "42"); - println(null() != "42"); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Object.output --- a/graal/com.oracle.truffle.sl.test/tests/Object.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -null -42 -42 -why -zzz -zzz diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Object.sl --- a/graal/com.oracle.truffle.sl.test/tests/Object.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -function main() { - obj1 = new(); - println(obj1.x); - obj1.x = 42; - println(obj1.x); - - obj2 = new(); - obj2.o = obj1; - println(obj2.o.x); - obj2.o.y = "why"; - println(obj1.y); - - println(mkobj().z); - - obj3 = new(); - obj3.fn = mkobj; - println(obj3.fn().z); - - obj4 = new(); - write(obj4, 1); - read(obj4); - write(obj4, 2); - read(obj4); - write(obj4, "three"); - read(obj4); -} - -function mkobj() { - newobj = new(); - newobj.z = "zzz"; - return newobj; -} - -function read(obj) { - return obj.prop; -} - -function write(obj, value) { - return obj.prop = value; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/String.output --- a/graal/com.oracle.truffle.sl.test/tests/String.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -snull -snull -sbar -sfoo -nulls -nulls -bars -foos -2 < 4: true -Type error at String.sl line 9 col 34: operation "<" not defined for Number 2, String "4" diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/String.sl --- a/graal/com.oracle.truffle.sl.test/tests/String.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -function null() { -} - -function foo() { - return "bar"; -} - -function f(a, b) { - return a + " < " + b + ": " + (a < b); -} - -function main() { - println("s" + null()); - println("s" + null); - println("s" + foo()); - println("s" + foo); - - println(null() + "s"); - println(null() + "s"); - println(foo() + "s"); - println(foo + "s"); - - println(f(2, 4)); - println(f(2, "4")); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Sub.output --- a/graal/com.oracle.truffle.sl.test/tests/Sub.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ --1 --3999999999997 -2999999999996 --1000000000000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Sub.sl --- a/graal/com.oracle.truffle.sl.test/tests/Sub.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -function main() { - println(3 - 4); - println(3 - 4000000000000); - println(3000000000000 - 4); - println(3000000000000 - 4000000000000); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Sum.output --- a/graal/com.oracle.truffle.sl.test/tests/Sum.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -50005000 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/Sum.sl --- a/graal/com.oracle.truffle.sl.test/tests/Sum.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -function main() { - i = 0; - sum = 0; - while (i <= 10000) { - sum = sum + i; - i = i + 1; - } - return sum; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error at TypeError01.sl line 2 col 3: operation "-" not defined for Number 3, String "4" diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError01.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - 3 - "4"; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError02.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError02.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error at TypeError02.sl line 2 col 3: operation "if" not defined for String "4" diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError02.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError02.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - if ("4") { } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error at TypeError03.sl line 2 col 3: operation "&&" not defined for String "4", ANY diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - "4" && 4; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error at TypeError04.sl line 2 col 3: operation "||" not defined for Boolean false, Number 4 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - (1 > 2) || 4; -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError05.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError05.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error at TypeError05.sl line 3 col 3: operation "invoke" not defined for Boolean true diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError05.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError05.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -function main() { - f = 1 < 2; - f(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError06.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError06.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error: operation "defineFunction" not defined for Number 3 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError06.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError06.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - defineFunction(3); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError07.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError07.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Type error: operation "defineFunction" not defined for NULL diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/TypeError07.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError07.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - defineFunction(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/UndefinedFunction01.output --- a/graal/com.oracle.truffle.sl.test/tests/error/UndefinedFunction01.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Undefined function: foo diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests/error/UndefinedFunction01.sl --- a/graal/com.oracle.truffle.sl.test/tests/error/UndefinedFunction01.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function main() { - foo(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests_instrumentation/Instrumentation_assnCount.output --- a/graal/com.oracle.truffle.sl.test/tests_instrumentation/Instrumentation_assnCount.output Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -100 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -100 diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.test/tests_instrumentation/Instrumentation_assnCount.sl --- a/graal/com.oracle.truffle.sl.test/tests_instrumentation/Instrumentation_assnCount.sl Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -function loop(count) { - i = 0; - while (i < count) { - i = i + 1; - } - return i; -} - -function main() { - count = loop(100); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLHandler.java --- a/graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLHandler.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.sl.tools.debug; - -import java.util.*; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.tools.debug.shell.*; -import com.oracle.truffle.tools.debug.shell.client.*; -import com.oracle.truffle.tools.debug.shell.server.*; - -/** - * Instantiation of the "server handler" part of the "REPL*" debugger for the simple language. - *

- * These handlers implement debugging commands that require language-specific support. - * - * @see SimpleREPLClient - */ -public abstract class SLREPLHandler extends REPLHandler { - - protected SLREPLHandler(String op) { - super(op); - } - - public static final SLREPLHandler INFO_HANDLER = new SLREPLHandler(REPLMessage.INFO) { - - @Override - public REPLMessage[] receive(REPLMessage request, REPLServerContext serverContext) { - final String topic = request.get(REPLMessage.TOPIC); - - if (topic == null || topic.isEmpty()) { - final REPLMessage message = new REPLMessage(REPLMessage.OP, REPLMessage.INFO); - return finishReplyFailed(message, "No info topic specified"); - } - - switch (topic) { - - case REPLMessage.LANGUAGE: - return createLanguageInfoReply(); - - default: - final REPLMessage message = new REPLMessage(REPLMessage.OP, REPLMessage.INFO); - return finishReplyFailed(message, "No info about topic \"" + topic + "\""); - } - } - }; - - private static REPLMessage[] createLanguageInfoReply() { - final ArrayList langMessages = new ArrayList<>(); - - final REPLMessage msg1 = new REPLMessage(REPLMessage.OP, REPLMessage.INFO); - msg1.put(REPLMessage.TOPIC, REPLMessage.LANGUAGE); - msg1.put(REPLMessage.INFO_KEY, "Language"); - msg1.put(REPLMessage.INFO_VALUE, "Simple"); - msg1.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED); - langMessages.add(msg1); - - return langMessages.toArray(new REPLMessage[0]); - } - - public static final SLREPLHandler LOAD_RUN_SOURCE_HANDLER = new SLREPLHandler(REPLMessage.LOAD_RUN) { - - @Override - public REPLMessage[] receive(REPLMessage request, REPLServerContext serverContext) { - return loadHandler(request, serverContext, false); - } - }; - - public static final SLREPLHandler LOAD_STEP_SOURCE_HANDLER = new SLREPLHandler(REPLMessage.LOAD_STEP) { - - @Override - public REPLMessage[] receive(REPLMessage request, REPLServerContext serverContext) { - return loadHandler(request, serverContext, true); - } - }; - - /** - * Runs a source, optionally stepping into a specified tag. - */ - private static REPLMessage[] loadHandler(REPLMessage request, REPLServerContext serverContext, boolean stepInto) { - final REPLMessage reply = new REPLMessage(REPLMessage.OP, REPLMessage.LOAD_RUN); - final String fileName = request.get(REPLMessage.SOURCE_NAME); - try { - final Source source = Source.fromFileName(fileName, true); - if (source == null) { - return finishReplyFailed(reply, "can't find file \"" + fileName + "\""); - } - serverContext.getDebugEngine().run(source, stepInto); - reply.put(REPLMessage.FILE_PATH, source.getPath()); - return finishReplySucceeded(reply, source.getName() + " exited"); - } catch (QuitException ex) { - throw ex; - } catch (KillException ex) { - return finishReplySucceeded(reply, fileName + " killed"); - } catch (Exception ex) { - return finishReplyFailed(reply, "error loading file \"" + fileName + "\": " + ex.getMessage()); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java --- a/graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.sl.tools.debug; - -import java.util.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.*; -import com.oracle.truffle.api.vm.TruffleVM.Language; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.tools.debug.engine.*; -import com.oracle.truffle.tools.debug.shell.*; -import com.oracle.truffle.tools.debug.shell.client.*; -import com.oracle.truffle.tools.debug.shell.server.*; - -/** - * Instantiation of the "server" side of the "REPL*" debugger for the Simple language. - *

- * The SL parser is not equipped to parse program fragments, so any debugging functions that depend - * on this are not supported, for example {@link DebugEngine#eval(Source, Node, MaterializedFrame)} - * and {@link Breakpoint#setCondition(String)}. - * - * @see SimpleREPLClient - */ -public final class SLREPLServer implements REPLServer { - - // TODO (mlvdv) remove when there's a better way to express this dependency - @SuppressWarnings("unused") private static final Class DYNAMIC_DEPENDENCY = com.oracle.truffle.sl.SLLanguage.class; - - public static void main(String[] args) { - // Cheating for the prototype: start from SL, rather than from the client. - final SLREPLServer server = new SLREPLServer(); - final SimpleREPLClient client = new SimpleREPLClient(server.language.getShortName(), server); - - // Cheating for the prototype: allow server access to client for recursive debugging - server.setClient(client); - - try { - client.start(); - } catch (QuitException ex) { - } - } - - private final Language language; - private final DebugEngine slDebugEngine; - private final String statusPrefix; - private final Map handlerMap = new HashMap<>(); - private SLServerContext currentServerContext; - private SimpleREPLClient replClient = null; - - private void add(REPLHandler fileHandler) { - handlerMap.put(fileHandler.getOp(), fileHandler); - } - - public SLREPLServer() { - add(REPLHandler.BACKTRACE_HANDLER); - add(REPLHandler.BREAK_AT_LINE_HANDLER); - add(REPLHandler.BREAK_AT_LINE_ONCE_HANDLER); - add(REPLHandler.BREAK_AT_THROW_HANDLER); - add(REPLHandler.BREAK_AT_THROW_ONCE_HANDLER); - add(REPLHandler.BREAKPOINT_INFO_HANDLER); - add(REPLHandler.CLEAR_BREAK_HANDLER); - add(REPLHandler.CONTINUE_HANDLER); - add(REPLHandler.DELETE_HANDLER); - add(REPLHandler.DISABLE_BREAK_HANDLER); - add(REPLHandler.ENABLE_BREAK_HANDLER); - add(REPLHandler.FILE_HANDLER); - add(REPLHandler.FRAME_HANDLER); - add(SLREPLHandler.INFO_HANDLER); - add(REPLHandler.KILL_HANDLER); - add(SLREPLHandler.LOAD_RUN_SOURCE_HANDLER); - add(SLREPLHandler.LOAD_STEP_SOURCE_HANDLER); - add(REPLHandler.QUIT_HANDLER); - add(REPLHandler.STEP_INTO_HANDLER); - add(REPLHandler.STEP_OUT_HANDLER); - add(REPLHandler.STEP_OVER_HANDLER); - add(REPLHandler.TRUFFLE_HANDLER); - add(REPLHandler.TRUFFLE_NODE_HANDLER); - - TruffleVM vm = TruffleVM.newVM().build(); - this.language = vm.getLanguages().get("application/x-sl"); - assert language != null; - - final SLREPLDebugClient slDebugClient = new SLREPLDebugClient(language); - this.slDebugEngine = DebugEngine.create(slDebugClient, language); - - this.statusPrefix = language.getShortName() + " REPL:"; - } - - private void setClient(SimpleREPLClient replClient) { - this.replClient = replClient; - } - - public REPLMessage start() { - - this.currentServerContext = new SLServerContext(null, null, null); - - // SL doesn't load modules (like other languages), so we just return a success - final REPLMessage reply = new REPLMessage(); - reply.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED); - reply.put(REPLMessage.DISPLAY_MSG, language.getShortName() + " started"); - return reply; - } - - public REPLMessage[] receive(REPLMessage request) { - if (currentServerContext == null) { - final REPLMessage message = new REPLMessage(); - message.put(REPLMessage.STATUS, REPLMessage.FAILED); - message.put(REPLMessage.DISPLAY_MSG, "server not started"); - final REPLMessage[] reply = new REPLMessage[]{message}; - return reply; - } - return currentServerContext.receive(request); - } - - /** - * Execution context of a halted SL program. - */ - public final class SLServerContext extends REPLServerContext { - - private final SLServerContext predecessor; - - public SLServerContext(SLServerContext predecessor, Node astNode, MaterializedFrame mFrame) { - super(predecessor == null ? 0 : predecessor.getLevel() + 1, astNode, mFrame); - this.predecessor = predecessor; - } - - @Override - public REPLMessage[] receive(REPLMessage request) { - final String command = request.get(REPLMessage.OP); - final REPLHandler handler = handlerMap.get(command); - - if (handler == null) { - final REPLMessage message = new REPLMessage(); - message.put(REPLMessage.OP, command); - message.put(REPLMessage.STATUS, REPLMessage.FAILED); - message.put(REPLMessage.DISPLAY_MSG, statusPrefix + " op \"" + command + "\" not supported"); - final REPLMessage[] reply = new REPLMessage[]{message}; - return reply; - } - return handler.receive(request, currentServerContext); - } - - @Override - public Language getLanguage() { - return language; - } - - @Override - public DebugEngine getDebugEngine() { - return slDebugEngine; - } - - } - - /** - * Specialize the standard SL debug context by notifying the REPL client when execution is - * halted, e.g. at a breakpoint. - *

- * Before notification, the server creates a new context at the halted location, in which - * subsequent evaluations take place until such time as the client says to "continue". - *

- * This implementation "cheats" the intended asynchronous architecture by calling back directly - * to the client with the notification. - */ - private final class SLREPLDebugClient implements DebugClient { - - private final Language language; - - SLREPLDebugClient(Language language) { - this.language = language; - } - - public void haltedAt(Node node, MaterializedFrame mFrame, List warnings) { - // Create and push a new debug context where execution is halted - currentServerContext = new SLServerContext(currentServerContext, node, mFrame); - - // Message the client that execution is halted and is in a new debugging context - final REPLMessage message = new REPLMessage(); - message.put(REPLMessage.OP, REPLMessage.STOPPED); - final SourceSection src = node.getSourceSection(); - final Source source = src.getSource(); - message.put(REPLMessage.SOURCE_NAME, source.getName()); - message.put(REPLMessage.FILE_PATH, source.getPath()); - message.put(REPLMessage.LINE_NUMBER, Integer.toString(src.getStartLine())); - message.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED); - message.put(REPLMessage.DEBUG_LEVEL, Integer.toString(currentServerContext.getLevel())); - if (!warnings.isEmpty()) { - final StringBuilder sb = new StringBuilder(); - for (String warning : warnings) { - sb.append(warning + "\n"); - } - message.put(REPLMessage.WARNINGS, sb.toString()); - } - try { - // Cheat with synchrony: call client directly about entering a nested debugging - // context. - replClient.halted(message); - } finally { - // Returns when "continue" is called in the new debugging context - - // Pop the debug context, and return so that the old context will continue - currentServerContext = currentServerContext.predecessor; - } - } - - public Language getLanguage() { - return language; - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLAssertionError.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLAssertionError.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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.sl; - -/** - * An implementation of an {@link AssertionError} also containing the guest language stack trace. - */ -public class SLAssertionError extends AssertionError { - - private static final long serialVersionUID = -9138475336963945873L; - - public SLAssertionError(String message) { - super(message); - initCause(new AssertionError("Java stack trace")); - } - - @Override - public synchronized Throwable fillInStackTrace() { - return SLException.fillInSLStackTrace(this); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLException.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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.sl; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * SL does not need a sophisticated error checking and reporting mechanism, so all unexpected - * conditions just abort execution. This exception class is used when we abort from within the SL - * implementation. - */ -public class SLException extends RuntimeException { - - private static final long serialVersionUID = -6799734410727348507L; - - public SLException(String message) { - super(message); - initCause(new Throwable("Java stack trace")); - } - - @Override - public synchronized Throwable fillInStackTrace() { - return fillInSLStackTrace(this); - } - - /** - * Uses the Truffle API to iterate the stack frames and to create and set Java - * {@link StackTraceElement} elements based on the source sections of the call nodes on the - * stack. - */ - static Throwable fillInSLStackTrace(Throwable t) { - final List stackTrace = new ArrayList<>(); - Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { - public Void visitFrame(FrameInstance frame) { - Node callNode = frame.getCallNode(); - if (callNode == null) { - return null; - } - RootNode root = callNode.getRootNode(); - - /* - * There should be no RootNodes other than SLRootNodes on the stack. Just for the - * case if this would change. - */ - String methodName = "$unknownFunction"; - if (root instanceof SLRootNode) { - methodName = ((SLRootNode) root).getName(); - } - - SourceSection sourceSection = callNode.getEncapsulatingSourceSection(); - Source source = sourceSection != null ? sourceSection.getSource() : null; - String sourceName = source != null ? source.getName() : null; - int lineNumber; - try { - lineNumber = sourceSection != null ? sourceSection.getLineLocation().getLineNumber() : -1; - } catch (UnsupportedOperationException e) { - /* - * SourceSection#getLineLocation() may throw an UnsupportedOperationException. - */ - lineNumber = -1; - } - stackTrace.add(new StackTraceElement("SL", methodName, sourceName, lineNumber)); - return null; - } - }); - t.setStackTrace(stackTrace.toArray(new StackTraceElement[stackTrace.size()])); - return t; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,493 +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.sl; - -import java.io.*; -import java.math.*; -import java.net.*; -import java.util.*; -import java.util.Scanner; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.*; -import com.oracle.truffle.api.vm.TruffleVM.Symbol; -import com.oracle.truffle.sl.builtins.*; -import com.oracle.truffle.sl.factory.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.nodes.call.*; -import com.oracle.truffle.sl.nodes.controlflow.*; -import com.oracle.truffle.sl.nodes.expression.*; -import com.oracle.truffle.sl.nodes.instrument.*; -import com.oracle.truffle.sl.nodes.local.*; -import com.oracle.truffle.sl.parser.*; -import com.oracle.truffle.sl.runtime.*; -import com.oracle.truffle.tools.*; - -/** - * SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as - * simple and clean as possible in order to help understanding the ideas and concepts of Truffle. - * The language has first class functions, but no object model. - *

- * SL is dynamically typed, i.e., there are no type names specified by the programmer. SL is - * strongly typed, i.e., there is no automatic conversion between types. If an operation is not - * available for the types encountered at run time, a type error is reported and execution is - * stopped. For example, {@code 4 - "2"} results in a type error because subtraction is only defined - * for numbers. - * - *

- * Types: - *

    - *
  • Number: arbitrary precision integer numbers. The implementation uses the Java primitive type - * {@code long} to represent numbers that fit into the 64 bit range, and {@link BigInteger} for - * numbers that exceed the range. Using a primitive type such as {@code long} is crucial for - * performance. - *
  • Boolean: implemented as the Java primitive type {@code boolean}. - *
  • String: implemented as the Java standard type {@link String}. - *
  • Function: implementation type {@link SLFunction}. - *
  • Null (with only one value {@code null}): implemented as the singleton - * {@link SLNull#SINGLETON}. - *
- * The class {@link SLTypes} lists these types for the Truffle DSL, i.e., for type-specialized - * operations that are specified using Truffle DSL annotations. - * - *

- * Language concepts: - *

    - *
  • Literals for {@link SLBigIntegerLiteralNode numbers} , {@link SLStringLiteralNode strings}, - * and {@link SLFunctionLiteralNode functions}. - *
  • Basic arithmetic, logical, and comparison operations: {@link SLAddNode +}, {@link SLSubNode - * -}, {@link SLMulNode *}, {@link SLDivNode /}, {@link SLLogicalAndNode logical and}, - * {@link SLLogicalOrNode logical or}, {@link SLEqualNode ==}, !=, {@link SLLessThanNode <}, - * {@link SLLessOrEqualNode ≤}, >, ≥. - *
  • Local variables: local variables must be defined (via a {@link SLWriteLocalVariableNode - * write}) before they can be used (by a {@link SLReadLocalVariableNode read}). Local variables are - * not visible outside of the block where they were first defined. - *
  • Basic control flow statements: {@link SLBlockNode blocks}, {@link SLIfNode if}, - * {@link SLWhileNode while} with {@link SLBreakNode break} and {@link SLContinueNode continue}, - * {@link SLReturnNode return}. - *
  • Function calls: {@link SLInvokeNode invocations} are efficiently implemented with - * {@link SLDispatchNode polymorphic inline caches}. - *
- * - *

- * Syntax and parsing:
- * The syntax is described as an attributed grammar. The {@link Parser} and {@link Scanner} are - * automatically generated by the parser generator Coco/R (available from http://ssw.jku.at/coco/). The grammar contains semantic - * actions that build the AST for a method. To keep these semantic actions short, they are mostly - * calls to the {@link SLNodeFactory} that performs the actual node creation. All functions found in - * the SL source are added to the {@link SLFunctionRegistry}, which is accessible from the - * {@link SLContext}. - * - *

- * Builtin functions:
- * Library functions that are available to every SL source without prior definition are called - * builtin functions. They are added to the {@link SLFunctionRegistry} when the {@link SLContext} is - * created. There current builtin functions are - *

    - *
  • {@link SLReadlnBuiltin readln}: Read a String from the {@link SLContext#getInput() standard - * input}. - *
  • {@link SLPrintlnBuiltin println}: Write a value to the {@link SLContext#getOutput() standard - * output}. - *
  • {@link SLNanoTimeBuiltin nanoTime}: Returns the value of a high-resolution time, in - * nanoseconds. - *
  • {@link SLDefineFunctionBuiltin defineFunction}: Parses the functions provided as a String - * argument and adds them to the function registry. Functions that are already defined are replaced - * with the new version. - *
- * - *

- * Tools:
- * The use of some of Truffle's support for developer tools (based on the Truffle Instrumentation - * Framework) are demonstrated in this file, for example: - *

    - *
  • a {@linkplain NodeExecCounter counter for node executions}, tabulated by node type; and
  • - *
  • a simple {@linkplain CoverageTracker code coverage engine}.
  • - *
- * In each case, the tool is enabled if a corresponding local boolean variable in this file is set - * to {@code true}. Results are printed at the end of the execution using each tool's - * default printer. - * - */ -@TruffleLanguage.Registration(name = "SL", version = "0.5", mimeType = "application/x-sl") -public class SLLanguage extends TruffleLanguage { - private static SLLanguage LAST; - private static List> builtins = Collections.emptyList(); - private static Visualizer visualizer = new SLDefaultVisualizer(); - private static ASTProber registeredASTProber; // non-null if prober already registered - private final SLContext context; - private DebugSupportProvider debugSupport; - - public SLLanguage(Env env) { - super(env); - context = SLContextFactory.create(new BufferedReader(env().stdIn()), new PrintWriter(env().stdOut(), true)); - LAST = this; - for (NodeFactory builtin : builtins) { - context.installBuiltin(builtin); - } - } - - // TODO (mlvdv) command line options - /* Enables demonstration of per-type tabulation of node execution counts */ - private static boolean nodeExecCounts = false; - /* Enables demonstration of per-line tabulation of STATEMENT node execution counts */ - private static boolean statementCounts = false; - /* Enables demonstration of per-line tabulation of STATEMENT coverage */ - private static boolean coverage = false; - - /* Small tools that can be installed for demonstration */ - private static NodeExecCounter nodeExecCounter = null; - private static NodeExecCounter statementExecCounter = null; - private static CoverageTracker coverageTracker = null; - - /** - * The main entry point. Use the mx command "mx sl" to run it with the correct class path setup. - */ - public static void main(String[] args) throws IOException { - TruffleVM vm = TruffleVM.newVM().build(); - assert vm.getLanguages().containsKey("application/x-sl"); - - setupToolDemos(); - - int repeats = 1; - if (args.length >= 2) { - repeats = Integer.parseInt(args[1]); - } - - if (args.length == 0) { - vm.eval("application/x-sl", new InputStreamReader(System.in)); - } else { - vm.eval(new File(args[0]).toURI()); - } - Symbol main = vm.findGlobalSymbol("main"); - if (main == null) { - throw new SLException("No function main() defined in SL source file."); - } - while (repeats-- > 0) { - main.invoke(null); - } - reportToolDemos(); - } - - /** - * Temporary method during API evolution, supports debugger integration. - */ - public static void run(Source source) throws IOException { - TruffleVM vm = TruffleVM.newVM().build(); - assert vm.getLanguages().containsKey("application/x-sl"); - vm.eval(new File(source.getPath()).toURI()); - Symbol main = vm.findGlobalSymbol("main"); - if (main == null) { - throw new SLException("No function main() defined in SL source file."); - } - main.invoke(null); - } - - /** - * Parse and run the specified SL source. Factored out in a separate method so that it can also - * be used by the unit test harness. - */ - public static long run(TruffleVM context, URI source, PrintWriter logOutput, PrintWriter out, int repeats, List> currentBuiltins) throws IOException { - builtins = currentBuiltins; - - if (logOutput != null) { - logOutput.println("== running on " + Truffle.getRuntime().getName()); - // logOutput.println("Source = " + source.getCode()); - } - - /* Parse the SL source file. */ - Object result = context.eval(source); - if (result != null) { - out.println(result); - } - - /* Lookup our main entry point, which is per definition always named "main". */ - Symbol main = context.findGlobalSymbol("main"); - if (main == null) { - throw new SLException("No function main() defined in SL source file."); - } - - /* Change to true if you want to see the AST on the console. */ - boolean printASTToLog = false; - /* Change to true if you want to see source attribution for the AST to the console */ - boolean printSourceAttributionToLog = false; - /* Change to dump the AST to IGV over the network. */ - boolean dumpASTToIGV = false; - - printScript("before execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV); - long totalRuntime = 0; - try { - for (int i = 0; i < repeats; i++) { - long start = System.nanoTime(); - /* Call the main entry point, without any arguments. */ - try { - result = main.invoke(null); - if (result != null) { - out.println(result); - } - } catch (UnsupportedSpecializationException ex) { - out.println(formatTypeError(ex)); - } catch (SLUndefinedFunctionException ex) { - out.println(String.format("Undefined function: %s", ex.getFunctionName())); - } - long end = System.nanoTime(); - totalRuntime += end - start; - - if (logOutput != null && repeats > 1) { - logOutput.println("== iteration " + (i + 1) + ": " + ((end - start) / 1000000) + " ms"); - } - } - - } finally { - printScript("after execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV); - } - return totalRuntime; - } - - /** - * When dumpASTToIGV is true: dumps the AST of all functions to the IGV visualizer, via a socket - * connection. IGV can be started with the mx command "mx igv". - *

- * When printASTToLog is true: prints the ASTs to the console. - */ - private static void printScript(String groupName, SLContext context, PrintWriter logOutput, boolean printASTToLog, boolean printSourceAttributionToLog, boolean dumpASTToIGV) { - if (dumpASTToIGV) { - GraphPrintVisitor graphPrinter = new GraphPrintVisitor(); - graphPrinter.beginGroup(groupName); - for (SLFunction function : context.getFunctionRegistry().getFunctions()) { - RootCallTarget callTarget = function.getCallTarget(); - if (callTarget != null) { - graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode()); - } - } - graphPrinter.printToNetwork(true); - } - if (printASTToLog && logOutput != null) { - for (SLFunction function : context.getFunctionRegistry().getFunctions()) { - RootCallTarget callTarget = function.getCallTarget(); - if (callTarget != null) { - logOutput.println("=== " + function); - NodeUtil.printTree(logOutput, callTarget.getRootNode()); - } - } - } - if (printSourceAttributionToLog && logOutput != null) { - for (SLFunction function : context.getFunctionRegistry().getFunctions()) { - RootCallTarget callTarget = function.getCallTarget(); - if (callTarget != null) { - logOutput.println("=== " + function); - NodeUtil.printSourceAttributionTree(logOutput, callTarget.getRootNode()); - } - } - } - } - - /** - * Provides a user-readable message for run-time type errors. SL is strongly typed, i.e., there - * are no automatic type conversions of values. Therefore, Truffle does the type checking for - * us: if no matching node specialization for the actual values is found, then we have a type - * error. Specialized nodes use the {@link UnsupportedSpecializationException} to report that no - * specialization was found. We therefore just have to convert the information encapsulated in - * this exception in a user-readable form. - */ - private static String formatTypeError(UnsupportedSpecializationException ex) { - StringBuilder result = new StringBuilder(); - result.append("Type error"); - if (ex.getNode() != null && ex.getNode().getSourceSection() != null) { - SourceSection ss = ex.getNode().getSourceSection(); - if (ss != null && !(ss instanceof NullSourceSection)) { - result.append(" at ").append(ss.getSource().getShortName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn()); - } - } - result.append(": operation"); - if (ex.getNode() != null) { - NodeInfo nodeInfo = SLContext.lookupNodeInfo(ex.getNode().getClass()); - if (nodeInfo != null) { - result.append(" \"").append(nodeInfo.shortName()).append("\""); - } - } - result.append(" not defined for"); - - String sep = " "; - for (int i = 0; i < ex.getSuppliedValues().length; i++) { - Object value = ex.getSuppliedValues()[i]; - Node node = ex.getSuppliedNodes()[i]; - if (node != null) { - result.append(sep); - sep = ", "; - - if (value instanceof Long || value instanceof BigInteger) { - result.append("Number ").append(value); - } else if (value instanceof Boolean) { - result.append("Boolean ").append(value); - } else if (value instanceof String) { - result.append("String \"").append(value).append("\""); - } else if (value instanceof SLFunction) { - result.append("Function ").append(value); - } else if (value == SLNull.SINGLETON) { - result.append("NULL"); - } else if (value == null) { - // value is not evaluated because of short circuit evaluation - result.append("ANY"); - } else { - result.append(value); - } - } - } - return result.toString(); - } - - @Override - protected Object eval(Source code) throws IOException { - try { - context.evalSource(code); - } catch (Exception e) { - throw new IOException(e); - } - return null; - } - - @Override - protected Object findExportedSymbol(String globalName, boolean onlyExplicit) { - for (SLFunction f : context.getFunctionRegistry().getFunctions()) { - if (globalName.equals(f.getName())) { - return f; - } - } - return null; - } - - @Override - protected Object getLanguageGlobal() { - return context; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return object instanceof SLFunction; - } - - @Override - protected ToolSupportProvider getToolSupport() { - return getDebugSupport(); - } - - @Override - protected DebugSupportProvider getDebugSupport() { - if (debugSupport == null) { - debugSupport = new SLDebugProvider(); - } - return debugSupport; - } - - // TODO (mlvdv) remove the static hack when we no longer have the static demo variables - private static void setupToolDemos() { - if (statementCounts || coverage) { - if (registeredASTProber == null) { - final ASTProber newProber = new SLStandardASTProber(); - // This should be registered on the TruffleVM - Probe.registerASTProber(newProber); - registeredASTProber = newProber; - } - } - if (nodeExecCounts) { - nodeExecCounter = new NodeExecCounter(); - nodeExecCounter.install(); - } - - if (statementCounts) { - statementExecCounter = new NodeExecCounter(StandardSyntaxTag.STATEMENT); - statementExecCounter.install(); - } - - if (coverage) { - coverageTracker = new CoverageTracker(); - coverageTracker.install(); - } - } - - private static void reportToolDemos() { - if (nodeExecCounter != null) { - nodeExecCounter.print(System.out); - nodeExecCounter.dispose(); - } - if (statementExecCounter != null) { - statementExecCounter.print(System.out); - statementExecCounter.dispose(); - } - if (coverageTracker != null) { - coverageTracker.print(System.out); - coverageTracker.dispose(); - } - } - - private final class SLDebugProvider implements DebugSupportProvider { - - public SLDebugProvider() { - if (registeredASTProber == null) { - registeredASTProber = new SLStandardASTProber(); - // This should be registered on the TruffleVM - Probe.registerASTProber(registeredASTProber); - } - } - - public Visualizer getVisualizer() { - if (visualizer == null) { - visualizer = new SLDefaultVisualizer(); - } - return visualizer; - } - - public void enableASTProbing(ASTProber prober) { - if (prober != null) { - // This should be registered on the TruffleVM - Probe.registerASTProber(prober); - } - } - - public void run(Source source) throws DebugSupportException { - // TODO (mlvdv) fix to run properly in the current VM - try { - SLLanguage.run(source); - } catch (Exception e) { - throw new DebugSupportException(e); - } - } - - public Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugSupportException { - throw new DebugSupportException("evalInContext not supported in this language"); - } - - public AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugSupportException { - throw new DebugSupportException("createAdvancedInstrumentRootFactory not supported in this language"); - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertFalseBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertFalseBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.sl.builtins; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Asserts a given value to be false and throws an {@link AssertionError} if the value - * was true. - */ -@NodeInfo(shortName = "assertFalse") -public abstract class SLAssertFalseBuiltin extends SLBuiltinNode { - - public SLAssertFalseBuiltin() { - super(new NullSourceSection("SL builtin", "assertFalse")); - } - - @Specialization - public boolean doAssert(boolean value, String message) { - if (value) { - CompilerDirectives.transferToInterpreter(); - throw new SLAssertionError(message == null ? "" : message); - } - return value; - } - - @Specialization - public boolean doAssertNull(boolean value, @SuppressWarnings("unused") SLNull message) { - return doAssert(value, null); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertTrueBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertTrueBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.sl.builtins; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Asserts a given value to be true and throws an {@link AssertionError} if the value - * was false. - */ -@NodeInfo(shortName = "assertTrue") -public abstract class SLAssertTrueBuiltin extends SLBuiltinNode { - - public SLAssertTrueBuiltin() { - super(new NullSourceSection("SL builtin", "assertTrue")); - } - - @Specialization - public boolean doAssert(boolean value, String message) { - if (!value) { - CompilerDirectives.transferToInterpreter(); - throw new SLAssertionError(message == null ? "" : message); - } - return value; - } - - @Specialization - public boolean doAssertNull(boolean value, @SuppressWarnings("unused") SLNull message) { - return doAssert(value, null); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Base class for all builtin functions. It contains the Truffle DSL annotation {@link NodeChild} - * that defines the function arguments.
- * Builtin functions need access to the {@link SLContext}. Instead of defining a Java field manually - * and setting it in a constructor, we use the Truffle DSL annotation {@link NodeField} that - * generates the field and constructor automatically. - *

- * The builtin functions are registered in {@link SLContext#installBuiltins}. Every builtin node - * subclass is instantiated there, wrapped into a function, and added to the - * {@link SLFunctionRegistry}. This ensures that builtin functions can be called like user-defined - * functions; there is no special function lookup or call node for builtin functions. - */ -@NodeChild(value = "arguments", type = SLExpressionNode[].class) -@NodeField(name = "context", type = SLContext.class) -@GenerateNodeFactory -public abstract class SLBuiltinNode extends SLExpressionNode { - - public SLBuiltinNode(SourceSection src) { - super(src); - } - - /** - * Accessor for the {@link SLContext}. The implementation of this method is generated - * automatically based on the {@link NodeField} annotation on the class. - */ - public abstract SLContext getContext(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.parser.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Builtin function to define (or redefine) functions. The provided source code is parsed the same - * way as the initial source of the script, so the same syntax applies. - */ -@NodeInfo(shortName = "defineFunction") -public abstract class SLDefineFunctionBuiltin extends SLBuiltinNode { - - public SLDefineFunctionBuiltin() { - super(new NullSourceSection("SL builtin", "defineFunction")); - } - - @Specialization - public String defineFunction(String code) { - doDefineFunction(getContext(), code); - return code; - } - - @TruffleBoundary - private static void doDefineFunction(SLContext context, String code) { - Source source = Source.fromText(code, "[defineFunction]"); - /* The same parsing code as for parsing the initial source. */ - Parser.parseSL(context, source); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * This builtin sets the variable named "hello" in the caller frame to the string "world". - */ -@NodeInfo(shortName = "helloEqualsWorld") -public abstract class SLHelloEqualsWorldBuiltin extends SLBuiltinNode { - - public SLHelloEqualsWorldBuiltin() { - super(new NullSourceSection("SL builtin", "helloEqualsWorld")); - } - - @Specialization - @TruffleBoundary - public String change() { - FrameInstance frameInstance = Truffle.getRuntime().getCallerFrame(); - Frame frame = frameInstance.getFrame(FrameAccess.READ_WRITE, false); - FrameSlot slot = frame.getFrameDescriptor().findOrAddFrameSlot("hello"); - frame.setObject(slot, "world"); - return "world"; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Builtin function that returns the value of a high-resolution time, in nanoseconds. - */ -@NodeInfo(shortName = "nanoTime") -public abstract class SLNanoTimeBuiltin extends SLBuiltinNode { - - public SLNanoTimeBuiltin() { - super(new NullSourceSection("SL builtin", "nanoTime")); - } - - @Specialization - public long nanoTime() { - return System.nanoTime(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +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.sl.builtins; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Built-in function to create a new object. Objects in SL are simply made up of name/value pairs. - */ -@NodeInfo(shortName = "new") -public abstract class SLNewObjectBuiltin extends SLBuiltinNode { - - public SLNewObjectBuiltin() { - super(new NullSourceSection("SL builtin", "new")); - } - - @Specialization - public Object newObject() { - return getContext().createObject(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import java.io.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Builtin function to write a value to the {@link SLContext#getOutput() standard output}. The - * different specialization leverage the typed {@code println} methods available in Java, i.e., - * primitive values are printed without converting them to a {@link String} first. - *

- * Printing involves a lot of Java code, so we need to tell the optimizing system that it should not - * unconditionally inline everything reachable from the println() method. This is done via the - * {@link TruffleBoundary} annotations. - */ -@NodeInfo(shortName = "println") -public abstract class SLPrintlnBuiltin extends SLBuiltinNode { - - public SLPrintlnBuiltin() { - super(new NullSourceSection("SL builtin", "println")); - } - - @Specialization - public long println(long value) { - doPrint(getContext().getOutput(), value); - return value; - } - - @TruffleBoundary - private static void doPrint(PrintWriter out, long value) { - out.println(value); - } - - @Specialization - public boolean println(boolean value) { - doPrint(getContext().getOutput(), value); - return value; - } - - @TruffleBoundary - private static void doPrint(PrintWriter out, boolean value) { - out.println(value); - } - - @Specialization - public String println(String value) { - doPrint(getContext().getOutput(), value); - return value; - } - - @TruffleBoundary - private static void doPrint(PrintWriter out, String value) { - out.println(value); - } - - @Specialization - public Object println(Object value) { - doPrint(getContext().getOutput(), value); - return value; - } - - @TruffleBoundary - private static void doPrint(PrintWriter out, Object value) { - out.println(value); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +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.sl.builtins; - -import java.io.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Builtin function that reads a String from the {@link SLContext#getInput() standard input}. - */ -@NodeInfo(shortName = "readln") -public abstract class SLReadlnBuiltin extends SLBuiltinNode { - - public SLReadlnBuiltin() { - super(new NullSourceSection("SL builtin", "readln")); - } - - @Specialization - public String readln() { - String result = doRead(getContext().getInput()); - if (result == null) { - /* - * We do not have a sophisticated end of file handling, so returning an empty string is - * a reasonable alternative. Note that the Java null value should never be used, since - * it can interfere with the specialization logic in generated source code. - */ - result = ""; - } - return result; - } - - @TruffleBoundary - private static String doRead(BufferedReader in) { - try { - return in.readLine(); - } catch (IOException ex) { - throw new SLException(ex.getMessage()); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.builtins; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Returns a string representation of the current stack. This includes the {@link CallTarget}s and - * the contents of the {@link Frame}. Note that this is implemented as a slow path by passing - * {@code true} to {@link FrameInstance#getFrame(FrameAccess, boolean)}. - */ -@NodeInfo(shortName = "stacktrace") -public abstract class SLStackTraceBuiltin extends SLBuiltinNode { - - public SLStackTraceBuiltin() { - super(new NullSourceSection("SL builtin", "stacktrace")); - } - - @Specialization - public String trace() { - return createStackTrace(); - } - - @TruffleBoundary - private static String createStackTrace() { - final StringBuilder str = new StringBuilder(); - - Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { - @Override - public Integer visitFrame(FrameInstance frameInstance) { - CallTarget callTarget = frameInstance.getCallTarget(); - Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY, true); - RootNode rn = ((RootCallTarget) callTarget).getRootNode(); - if (rn.getClass().getName().contains("SLFunctionForeignAccess")) { - return 1; - } - if (str.length() > 0) { - str.append(System.getProperty("line.separator")); - } - str.append("Frame: ").append(rn.toString()); - FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); - for (FrameSlot s : frameDescriptor.getSlots()) { - str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s)); - } - return null; - } - }); - return str.toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/factory/SLContextFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/factory/SLContextFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.factory; - -import java.io.*; - -import com.oracle.truffle.sl.runtime.*; - -public final class SLContextFactory { - - private SLContextFactory() { - } - - public static SLContext create(BufferedReader input, PrintWriter output) { - return new SLContext(input, output); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.source.*; - -/** - * Utility base class for operations that take two arguments (per convention called "left" and - * "right"). For concrete subclasses of this class, the Truffle DSL creates two child fields, and - * the necessary constructors and logic to set them. - */ -@NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")}) -public abstract class SLBinaryNode extends SLExpressionNode { - - public SLBinaryNode(SourceSection src) { - super(src); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +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.sl.nodes; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.instrument.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Base class for all SL nodes that produce a value and therefore benefit from type specialization. - * The annotation {@link TypeSystemReference} specifies the SL types. Specifying it here defines the - * type system for all subclasses. - */ -@TypeSystemReference(SLTypes.class) -@NodeInfo(description = "The abstract base node for all expressions") -public abstract class SLExpressionNode extends SLStatementNode { - - public SLExpressionNode(SourceSection src) { - super(src); - } - - /** - * The execute method when no specialization is possible. This is the most general case, - * therefore it must be provided by all subclasses. - */ - public abstract Object executeGeneric(VirtualFrame frame); - - /** - * When we use an expression at places where a {@link SLStatementNode statement} is already - * sufficient, the return value is just discarded. - */ - @Override - public void executeVoid(VirtualFrame frame) { - executeGeneric(frame); - } - - /* - * Execute methods for specialized types. They all follow the same pattern: they call the - * generic execution method and then expect a result of their return type. Type-specialized - * subclasses overwrite the appropriate methods. - */ - - public long executeLong(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectLong(executeGeneric(frame)); - } - - public SLFunction executeFunction(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectSLFunction(executeGeneric(frame)); - } - - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectBoolean(executeGeneric(frame)); - } - - @Override - public boolean isInstrumentable() { - return true; - } - - @Override - public WrapperNode createWrapperNode() { - return new SLExpressionWrapperNode(this); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes; - -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.builtins.*; -import com.oracle.truffle.sl.nodes.controlflow.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The root of all SL execution trees. It is a Truffle requirement that the tree root extends the - * class {@link RootNode}. This class is used for both builtin and user-defined functions. For - * builtin functions, the {@link #bodyNode} is a subclass of {@link SLBuiltinNode}. For user-defined - * functions, the {@link #bodyNode} is a {@link SLFunctionBodyNode}. - */ -@NodeInfo(language = "Simple Language", description = "The root of all Simple Language execution trees") -public final class SLRootNode extends RootNode { - - /** The function body that is executed, and specialized during execution. */ - @Child private SLExpressionNode bodyNode; - - /** The name of the function, for printing purposes only. */ - private final String name; - - /** The Simple execution context for this tree. **/ - private final SLContext context; - - @CompilationFinal private boolean isCloningAllowed; - - public SLRootNode(SLContext context, FrameDescriptor frameDescriptor, SLExpressionNode bodyNode, String name) { - super(null, frameDescriptor); - this.bodyNode = bodyNode; - this.name = name; - this.context = context; - } - - @Override - public Object execute(VirtualFrame frame) { - return bodyNode.executeGeneric(frame); - } - - public String getName() { - return name; - } - - public void setCloningAllowed(boolean isCloningAllowed) { - this.isCloningAllowed = isCloningAllowed; - } - - public SLExpressionNode getBodyNode() { - return bodyNode; - } - - @Override - public boolean isCloningAllowed() { - return isCloningAllowed; - } - - @Override - public void applyInstrumentation() { - Probe.applyASTProbers(bodyNode); - } - - @Override - public String toString() { - return "root " + name; - } - - public SLContext getSLContext() { - return this.context; - } - - @Override - public ExecutionContext getExecutionContext() { - return this.context; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +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.sl.nodes; - -import java.io.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.instrument.*; - -/** - * The base class of all Truffle nodes for SL. All nodes (even expressions) can be used as - * statements, i.e., without returning a value. The {@link VirtualFrame} provides access to the - * local variables. - */ -@NodeInfo(language = "Simple Language", description = "The abstract base node for all statements") -public abstract class SLStatementNode extends Node { - - public SLStatementNode(SourceSection src) { - super(src); - } - - /** - * Execute this node as as statement, where no return value is necessary. - */ - public abstract void executeVoid(VirtualFrame frame); - - public SLStatementNode getNonWrapperNode() { - return this; - } - - @Override - public String toString() { - return formatSourceSection(this); - } - - /** - * Formats a source section of a node in human readable form. If no source section could be - * found it looks up the parent hierarchy until it finds a source section. Nodes where this was - * required append a '~' at the end. - * - * @param node the node to format. - * @return a formatted source section string - */ - public static String formatSourceSection(Node node) { - if (node == null) { - return ""; - } - SourceSection section = node.getSourceSection(); - boolean estimated = false; - if (section == null) { - section = node.getEncapsulatingSourceSection(); - estimated = true; - } - - if (section == null || section.getSource() == null) { - return ""; - } else { - String sourceName = new File(section.getSource().getName()).getName(); - int startLine = section.getStartLine(); - return String.format("%s:%d%s", sourceName, startLine, estimated ? "~" : ""); - } - } - - @Override - public boolean isInstrumentable() { - return true; - } - - @Override - public WrapperNode createWrapperNode() { - return new SLStatementWrapperNode(this); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The type system of SL, as explained in {@link SLLanguage}. Based on the {@link TypeSystem} - * annotation, the Truffle DSL generates the subclass {@link SLTypesGen} with type test and type - * conversion methods for all types. In this class, we only cover types where the automatically - * generated ones would not be sufficient. - */ -@TypeSystem({long.class, BigInteger.class, boolean.class, String.class, SLFunction.class, SLNull.class}) -@DSLOptions(useNewLayout = true) -public abstract class SLTypes { - - /** - * Example of a manually specified type check that replaces the automatically generated type - * check that the Truffle DSL would generate. For {@link SLNull}, we do not need an - * {@code instanceof} check, because we know that there is only a {@link SLNull#SINGLETON - * singleton} instance. - */ - @TypeCheck(SLNull.class) - public static boolean isSLNull(Object value) { - return value == SLNull.SINGLETON; - } - - /** - * Example of a manually specified type cast that replaces the automatically generated type cast - * that the Truffle DSL would generate. For {@link SLNull}, we do not need an actual cast, - * because we know that there is only a {@link SLNull#SINGLETON singleton} instance. - */ - @TypeCast(SLNull.class) - public static SLNull asSLNull(Object value) { - assert isSLNull(value); - return SLNull.SINGLETON; - } - - /** - * Informs the Truffle DSL that a primitive {@code long} value can be used in all - * specializations where a {@link BigInteger} is expected. This models the semantic of SL: It - * only has an arbitrary precision Number type (implemented as {@link BigInteger}, and - * {@code long} is only used as a performance optimization to avoid the costly - * {@link BigInteger} arithmetic for values that fit into a 64-bit primitive value. - */ - @ImplicitCast - public static BigInteger castBigInteger(long value) { - return BigInteger.valueOf(value); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +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.sl.nodes.access; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.sl.runtime.*; - -public abstract class SLReadPropertyCacheNode extends Node { - - protected static final int CACHE_LIMIT = 3; - - protected final String propertyName; - - public SLReadPropertyCacheNode(String propertyName) { - this.propertyName = propertyName; - } - - public static SLReadPropertyCacheNode create(String propertyName) { - return SLReadPropertyCacheNodeGen.create(propertyName); - } - - public abstract Object executeObject(DynamicObject receiver); - - public abstract long executeLong(DynamicObject receiver) throws UnexpectedResultException; - - /* - * We use a separate long specialization to avoid boxing for long. - */ - @Specialization(limit = "CACHE_LIMIT", guards = {"longLocation != null", "shape.check(receiver)"}, assumptions = "shape.getValidAssumption()") - @SuppressWarnings("unused") - protected long doCachedLong(DynamicObject receiver, // - @Cached("receiver.getShape()") Shape shape, // - @Cached("getLongLocation(shape)") LongLocation longLocation) { - return longLocation.getLong(receiver, true); - } - - protected LongLocation getLongLocation(Shape shape) { - Property property = shape.getProperty(propertyName); - if (property != null && property.getLocation() instanceof LongLocation) { - return (LongLocation) property.getLocation(); - } - return null; - } - - /* - * As soon as we have seen an object read, we cannot avoid boxing long anymore therefore we can - * contain all long cache entries. - */ - @Specialization(limit = "CACHE_LIMIT", contains = "doCachedLong", guards = "shape.check(receiver)", assumptions = "shape.getValidAssumption()") - protected static Object doCachedObject(DynamicObject receiver, // - @Cached("receiver.getShape()") Shape shape, // - @Cached("shape.getProperty(propertyName)") Property property) { - if (property == null) { - return SLNull.SINGLETON; - } else { - return property.get(receiver, shape); - } - } - - /* - * The generic case is used if the number of shapes accessed overflows the limit. - */ - @Specialization(contains = "doCachedObject") - @TruffleBoundary - protected Object doGeneric(DynamicObject receiver, @Cached("new()") LRUPropertyLookup lruCache) { - if (!lruCache.shape.check(receiver)) { - Shape receiverShape = receiver.getShape(); - lruCache.shape = receiverShape; - lruCache.property = receiverShape.getProperty(propertyName); - } - if (lruCache.property != null) { - return lruCache.property.get(receiver, true); - } else { - return SLNull.SINGLETON; - } - } - - protected static class LRUPropertyLookup { - - private Shape shape; - private Property property; - - public LRUPropertyLookup() { - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.sl.nodes.access; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The node for accessing a property of an object. When executed, this node first evaluates the - * object expression on the left side of the dot operator and then reads the named property. - */ -@NodeInfo(shortName = ".") -public final class SLReadPropertyNode extends SLExpressionNode { - - public static SLReadPropertyNode create(SourceSection src, SLExpressionNode receiverNode, String propertyName) { - return new SLReadPropertyNode(src, receiverNode, propertyName); - } - - @Child private SLExpressionNode receiverNode; - @Child private SLReadPropertyCacheNode cacheNode; - private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile(); - - private SLReadPropertyNode(SourceSection src, SLExpressionNode receiverNode, String propertyName) { - super(src); - this.receiverNode = receiverNode; - this.cacheNode = SLReadPropertyCacheNodeGen.create(propertyName); - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - Object object = receiverNode.executeGeneric(frame); - if (receiverTypeCondition.profile(SLContext.isSLObject(object))) { - return cacheNode.executeObject(SLContext.castSLObject(object)); - } else { - throw new SLException("unexpected receiver type"); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyCacheNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyCacheNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +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.sl.nodes.access; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.object.*; - -public abstract class SLWritePropertyCacheNode extends Node { - - protected final String propertyName; - - public SLWritePropertyCacheNode(String propertyName) { - this.propertyName = propertyName; - } - - public abstract void executeObject(DynamicObject receiver, Object value); - - @Specialization(guards = "location.isValid(receiver, value)", assumptions = "location.getAssumptions()") - public void writeCached(DynamicObject receiver, Object value, // - @Cached("createCachedWrite(receiver, value)") CachedWriteLocation location) { - if (location.writeUnchecked(receiver, value)) { - // write successful - } else { - executeObject(receiver, value); - } - } - - @Specialization(contains = "writeCached") - @TruffleBoundary - public void writeGeneric(DynamicObject receiver, Object value, // - @Cached("new(createCachedWrite(receiver, value))") LRUCachedWriteLocation lru) { - CachedWriteLocation location = lru.location; - if (!location.isValid(receiver, value) || !location.areAssumptionsValid()) { - location = createCachedWrite(receiver, value); - lru.location = location; - } - if (location.writeUnchecked(receiver, value)) { - // write successful - } else { - executeObject(receiver, value); - } - } - - protected CachedWriteLocation createCachedWrite(DynamicObject receiver, Object value) { - while (receiver.updateShape()) { - // multiple shape updates might be needed. - } - - Shape oldShape = receiver.getShape(); - Shape newShape; - Property property = oldShape.getProperty(propertyName); - - if (property != null && property.getLocation().canSet(receiver, value)) { - newShape = oldShape; - } else { - receiver.define(propertyName, value, 0); - newShape = receiver.getShape(); - property = newShape.getProperty(propertyName); - } - - if (!oldShape.check(receiver)) { - return createCachedWrite(receiver, value); - } - - return new CachedWriteLocation(oldShape, newShape, property.getLocation()); - - } - - protected static final class CachedWriteLocation { - - private final Shape oldShape; - private final Shape newShape; - private final Location location; - private final Assumption validLocation = Truffle.getRuntime().createAssumption(); - - public CachedWriteLocation(Shape oldShape, Shape newShape, Location location) { - this.oldShape = oldShape; - this.newShape = newShape; - this.location = location; - } - - public boolean areAssumptionsValid() { - return validLocation.isValid() && oldShape.getValidAssumption().isValid() && newShape.getValidAssumption().isValid(); - } - - public Assumption[] getAssumptions() { - return new Assumption[]{oldShape.getValidAssumption(), newShape.getValidAssumption(), validLocation}; - } - - public boolean isValid(DynamicObject receiver, Object value) { - return oldShape.check(receiver) && location.canSet(receiver, value); - } - - public boolean writeUnchecked(DynamicObject receiver, Object value) { - try { - if (oldShape == newShape) { - location.set(receiver, value, oldShape); - } else { - location.set(receiver, value, oldShape, newShape); - } - return true; - } catch (IncompatibleLocationException | FinalLocationException e) { - validLocation.invalidate(); - return false; - } - } - } - - protected static final class LRUCachedWriteLocation { - - private CachedWriteLocation location; - - public LRUCachedWriteLocation(CachedWriteLocation location) { - this.location = location; - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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.sl.nodes.access; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The node for setting a property of an object. When executed, this node first evaluates the value - * expression on the right hand side of the equals operator, followed by the object expression on - * the left side of the dot operator, and then sets the named property of this object to the new - * value if the property already exists or adds a new property. Finally, it returns the new value. - */ -@NodeInfo(shortName = ".=") -public final class SLWritePropertyNode extends SLExpressionNode { - - public static SLWritePropertyNode create(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) { - return new SLWritePropertyNode(src, receiverNode, propertyName, valueNode); - } - - @Child protected SLExpressionNode receiverNode; - protected final String propertyName; - @Child protected SLExpressionNode valueNode; - @Child protected SLWritePropertyCacheNode cacheNode; - private final ConditionProfile receiverTypeCondition = ConditionProfile.createBinaryProfile(); - - private SLWritePropertyNode(SourceSection src, SLExpressionNode receiverNode, String propertyName, SLExpressionNode valueNode) { - super(src); - this.receiverNode = receiverNode; - this.propertyName = propertyName; - this.valueNode = valueNode; - this.cacheNode = SLWritePropertyCacheNodeGen.create(propertyName); - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - Object value = valueNode.executeGeneric(frame); - Object object = receiverNode.executeGeneric(frame); - if (receiverTypeCondition.profile(SLContext.isSLObject(object))) { - cacheNode.executeObject(SLContext.castSLObject(object), value); - } else { - throw new SLException("unexpected receiver type"); - } - return value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDispatchNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDispatchNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +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.sl.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -public abstract class SLDispatchNode extends Node { - - protected static final int INLINE_CACHE_SIZE = 2; - - public abstract Object executeDispatch(VirtualFrame frame, SLFunction function, Object[] arguments); - - @Specialization(guards = "function.getCallTarget() == null") - protected Object doUndefinedFunction(SLFunction function, @SuppressWarnings("unused") Object[] arguments) { - throw new SLUndefinedFunctionException(function.getName()); - } - - /** - * Inline cached specialization of the dispatch. - * - *

- * Since SL is a quite simple language, the benefit of the inline cache is quite small: after - * checking that the actual function to be executed is the same as the cachedFuntion, we can - * safely execute the cached call target. You can reasonably argue that caching the call target - * is overkill, since we could just retrieve it via {@code function.getCallTarget()}. However, - * in a more complex language the lookup of the call target is usually much more complicated - * than in SL. In addition, caching the call target allows method inlining. - *

- * - *

- * {@code limit = "INLINE_CACHE_SIZE"} Specifies the limit number of inline cache specialization - * instantiations. - *

- *

- * {@code guards = "function == cachedFunction"} The inline cache check. Note that - * cachedFunction is a final field so that the compiler can optimize the check. - *

- *

- * {@code assumptions = "cachedFunction.getCallTargetStable()"} Support for function - * redefinition: When a function is redefined, the call target maintained by the SLFunction - * object is change. To avoid a check for that, we use an Assumption that is invalidated by the - * SLFunction when the change is performed. Since checking an assumption is a no-op in compiled - * code, the assumption check performed by the DSL does not add any overhead during optimized - * execution. - *

- * - * @see Cached - * @see Specialization - * - * @param function the dynamically provided function - * @param cachedFunction the cached function of the specialization instance - * @param callNode the {@link DirectCallNode} specifically created for the {@link CallTarget} in - * cachedFunction. - */ - @Specialization(limit = "INLINE_CACHE_SIZE", guards = "function == cachedFunction", assumptions = "cachedFunction.getCallTargetStable()") - protected static Object doDirect(VirtualFrame frame, SLFunction function, Object[] arguments, // - @Cached("function") SLFunction cachedFunction, // - @Cached("create(cachedFunction.getCallTarget())") DirectCallNode callNode) { - /* Inline cache hit, we are safe to execute the cached call target. */ - return callNode.call(frame, arguments); - } - - /** - * Slow-path code for a call, used when the polymorphic inline cache exceeded its maximum size - * specified in INLINE_CACHE_SIZE. Such calls are not optimized any further, e.g., - * no method inlining is performed. - */ - @Specialization(contains = "doDirect") - protected static Object doIndirect(VirtualFrame frame, SLFunction function, Object[] arguments, // - @Cached("create()") IndirectCallNode callNode) { - /* - * SL has a quite simple call lookup: just ask the function for the current call target, and - * call it. - */ - return callNode.call(frame, function.getCallTarget(), arguments); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +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.sl.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The node for function invocation in SL. Since SL has first class functions, the - * {@link SLFunction target function} can be computed by an {@link #functionNode arbitrary - * expression}. This node is responsible for evaluating this expression, as well as evaluating the - * {@link #argumentNodes arguments}. The actual dispatch is then delegated to a chain of - * {@link SLDispatchNode} that form a polymorphic inline cache. - */ -@NodeInfo(shortName = "invoke") -public final class SLInvokeNode extends SLExpressionNode { - - public static SLInvokeNode create(SourceSection src, SLExpressionNode function, SLExpressionNode[] arguments) { - return new SLInvokeNode(src, function, arguments); - } - - @Child private SLExpressionNode functionNode; - @Children private final SLExpressionNode[] argumentNodes; - @Child private SLDispatchNode dispatchNode; - - private SLInvokeNode(SourceSection src, SLExpressionNode functionNode, SLExpressionNode[] argumentNodes) { - super(src); - this.functionNode = functionNode; - this.argumentNodes = argumentNodes; - this.dispatchNode = SLDispatchNodeGen.create(); - } - - @Override - @ExplodeLoop - public Object executeGeneric(VirtualFrame frame) { - SLFunction function = evaluateFunction(frame); - - /* - * The number of arguments is constant for one invoke node. During compilation, the loop is - * unrolled and the execute methods of all arguments are inlined. This is triggered by the - * ExplodeLoop annotation on the method. The compiler assertion below illustrates that the - * array length is really constant. - */ - CompilerAsserts.compilationConstant(argumentNodes.length); - - Object[] argumentValues = new Object[argumentNodes.length]; - for (int i = 0; i < argumentNodes.length; i++) { - argumentValues[i] = argumentNodes[i].executeGeneric(frame); - } - - return dispatchNode.executeDispatch(frame, function, argumentValues); - } - - private SLFunction evaluateFunction(VirtualFrame frame) { - try { - /* - * The function node must evaluate to a SLFunction value, so we call - * function-specialized method. - */ - return functionNode.executeFunction(frame); - } catch (UnexpectedResultException ex) { - /* - * The function node evaluated to a non-function result. This is a type error in the SL - * program. We report it with the same exception that Truffle DSL generated nodes use to - * report type errors. - */ - throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult()); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUndefinedFunctionException.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUndefinedFunctionException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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.sl.nodes.call; - -public class SLUndefinedFunctionException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private final String functionName; - - public SLUndefinedFunctionException(String functionName) { - this.functionName = functionName; - } - - public String getFunctionName() { - return functionName; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * A statement node that just executes a list of other statements. - */ -@NodeInfo(shortName = "block", description = "The node implementing a source code block") -public final class SLBlockNode extends SLStatementNode { - - /** - * The array of child nodes. The annotation {@link com.oracle.truffle.api.nodes.Node.Children - * Children} informs Truffle that the field contains multiple children. It is a Truffle - * requirement that the field is {@code final} and an array of nodes. - */ - @Children private final SLStatementNode[] bodyNodes; - - public SLBlockNode(SourceSection src, SLStatementNode... bodyNodes) { - super(src); - this.bodyNodes = bodyNodes; - } - - /** - * Execute all child statements. The annotation {@link ExplodeLoop} triggers full unrolling of - * the loop during compilation. This allows the {@link SLStatementNode#executeVoid} method of - * all children to be inlined. - */ - @Override - @ExplodeLoop - public void executeVoid(VirtualFrame frame) { - /* - * This assertion illustrates that the array length is really a constant during compilation. - */ - CompilerAsserts.compilationConstant(bodyNodes.length); - - for (SLStatementNode statement : bodyNodes) { - statement.executeVoid(frame); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakException.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.nodes.*; - -/** - * Exception thrown by the {@link SLBreakNode break statement} and caught by the {@link SLWhileNode - * loop statement}. Since the exception is stateless, i.e., has no instance fields, we can use a - * {@link #SINGLETON} to avoid memory allocation during interpretation. - */ -public final class SLBreakException extends ControlFlowException { - - public static final SLBreakException SINGLETON = new SLBreakException(); - - private static final long serialVersionUID = -91013036379258890L; - - /* Prevent instantiation from outside. */ - private SLBreakException() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Implementation of the SL break statement. We need to unwind an unknown number of interpreter - * frames that are between this {@link SLBreakNode} and the {@link SLWhileNode} of the loop we are - * breaking out. This is done by throwing an {@link SLBreakException exception} that is caught by - * the {@link SLWhileNode#executeVoid loop node}. - */ -@NodeInfo(shortName = "break", description = "The node implementing a break statement") -public final class SLBreakNode extends SLStatementNode { - - public SLBreakNode(SourceSection src) { - super(src); - } - - @Override - public void executeVoid(VirtualFrame frame) { - throw SLBreakException.SINGLETON; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueException.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.nodes.*; - -/** - * Exception thrown by the {@link SLContinueNode continue statement} and caught by the - * {@link SLWhileNode loop statement}. Since the exception is stateless, i.e., has no instance - * fields, we can use a {@link #SINGLETON} to avoid memory allocation during interpretation. - */ -public final class SLContinueException extends ControlFlowException { - - public static final SLContinueException SINGLETON = new SLContinueException(); - - private static final long serialVersionUID = 5329687983726237188L; - - /* Prevent instantiation from outside. */ - private SLContinueException() { - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Implementation of the SL continue statement. We need to unwind an unknown number of interpreter - * frames that are between this {@link SLContinueNode} and the {@link SLWhileNode} of the loop we - * are continuing. This is done by throwing an {@link SLContinueException exception} that is caught - * by the {@link SLWhileNode#executeVoid loop node}. - */ -@NodeInfo(shortName = "continue", description = "The node implementing a continue statement") -public final class SLContinueNode extends SLStatementNode { - - public SLContinueNode(SourceSection src) { - super(src); - } - - @Override - public void executeVoid(VirtualFrame frame) { - throw SLContinueException.SINGLETON; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The body of a user-defined SL function. This is the node referenced by a {@link SLRootNode} for - * user-defined functions. It handles the return value of a function: the {@link SLReturnNode return - * statement} throws an {@link SLReturnException exception} with the return value. This node catches - * the exception. If the method ends without an explicit {@code return}, return the - * {@link SLNull#SINGLETON default null value}. - */ -@NodeInfo(shortName = "body") -public final class SLFunctionBodyNode extends SLExpressionNode { - - /** The body of the function. */ - @Child private SLStatementNode bodyNode; - - /** - * Profiling information, collected by the interpreter, capturing whether the function had an - * {@link SLReturnNode explicit return statement}. This allows the compiler to generate better - * code. - */ - private final BranchProfile exceptionTaken = BranchProfile.create(); - private final BranchProfile nullTaken = BranchProfile.create(); - - public SLFunctionBodyNode(SourceSection src, SLStatementNode bodyNode) { - super(src); - this.bodyNode = bodyNode; - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - try { - /* Execute the function body. */ - bodyNode.executeVoid(frame); - - } catch (SLReturnException ex) { - /* - * In the interpreter, record profiling information that the function has an explicit - * return. - */ - exceptionTaken.enter(); - /* The exception transports the actual return value. */ - return ex.getResult(); - } - - /* - * In the interpreter, record profiling information that the function ends without an - * explicit return. - */ - nullTaken.enter(); - /* Return the default null value. */ - return SLNull.SINGLETON; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.nodes.*; - -@NodeInfo(shortName = "if", description = "The node implementing a condional statement") -public final class SLIfNode extends SLStatementNode { - - /** - * The condition of the {@code if}. This in a {@link SLExpressionNode} because we require a - * result value. We do not have a node type that can only return a {@code boolean} value, so - * {@link #evaluateCondition executing the condition} can lead to a type error. - */ - @Child private SLExpressionNode conditionNode; - - /** Statement (or {@link SLBlockNode block}) executed when the condition is true. */ - @Child private SLStatementNode thenPartNode; - - /** Statement (or {@link SLBlockNode block}) executed when the condition is false. */ - @Child private SLStatementNode elsePartNode; - - /** - * Profiling information, collected by the interpreter, capturing the profiling information of - * the condition. This allows the compiler to generate better code for conditions that are - * always true or always false. Additionally the {@link CountingConditionProfile} implementation - * (as opposed to {@link BinaryConditionProfile} implementation) transmits the probability of - * the condition to be true to the compiler. - */ - private final ConditionProfile condition = ConditionProfile.createCountingProfile(); - - public SLIfNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { - super(src); - this.conditionNode = conditionNode; - this.thenPartNode = thenPartNode; - this.elsePartNode = elsePartNode; - } - - @Override - public void executeVoid(VirtualFrame frame) { - /* - * In the interpreter, record profiling information that the condition was executed and with - * which outcome. - */ - if (condition.profile(evaluateCondition(frame))) { - /* Execute the then-branch. */ - thenPartNode.executeVoid(frame); - } else { - /* Execute the else-branch (which is optional according to the SL syntax). */ - if (elsePartNode != null) { - elsePartNode.executeVoid(frame); - } - } - } - - private boolean evaluateCondition(VirtualFrame frame) { - try { - /* - * The condition must evaluate to a boolean value, so we call the boolean-specialized - * execute method. - */ - return conditionNode.executeBoolean(frame); - } catch (UnexpectedResultException ex) { - /* - * The condition evaluated to a non-boolean result. This is a type error in the SL - * program. We report it with the same exception that Truffle DSL generated nodes use to - * report type errors. - */ - throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult()); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.nodes.*; - -public final class SLRepeatingNode extends Node implements RepeatingNode { - - /** - * The condition of the loop. This in a {@link SLExpressionNode} because we require a result - * value. We do not have a node type that can only return a {@code boolean} value, so - * {@link #evaluateCondition executing the condition} can lead to a type error. - */ - @Child private SLExpressionNode conditionNode; - - /** Statement (or {@link SLBlockNode block}) executed as long as the condition is true. */ - @Child private SLStatementNode bodyNode; - - /** - * Profiling information, collected by the interpreter, capturing whether a {@code continue} - * statement was used in this loop. This allows the compiler to generate better code for loops - * without a {@code continue}. - */ - private final BranchProfile continueTaken = BranchProfile.create(); - private final BranchProfile breakTaken = BranchProfile.create(); - - public SLRepeatingNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode bodyNode) { - super(src); - this.conditionNode = conditionNode; - this.bodyNode = bodyNode; - } - - public boolean executeRepeating(VirtualFrame frame) { - if (evaluateCondition(frame)) { - try { - /* Execute the loop body. */ - bodyNode.executeVoid(frame); - } catch (SLContinueException ex) { - /* In the interpreter, record profiling information that the loop uses continue. */ - continueTaken.enter(); - /* Fall through to next loop iteration. */ - } catch (SLBreakException ex) { - /* In the interpreter, record profiling information that the loop uses break. */ - breakTaken.enter(); - /* Done executing this loop, exit method to execute statement following the loop. */ - return false; - } - return true; - } else { - return false; - } - } - - private boolean evaluateCondition(VirtualFrame frame) { - try { - /* - * The condition must evaluate to a boolean value, so we call the boolean-specialized - * execute method. - */ - return (conditionNode.executeBoolean(frame)); - } catch (UnexpectedResultException ex) { - /* - * The condition evaluated to a non-boolean result. This is a type error in the SL - * program. We report it with the same exception that Truffle DSL generated nodes use to - * report type errors. - */ - throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult()); - } - } - - @Override - public String toString() { - return SLStatementNode.formatSourceSection(this); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnException.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.nodes.*; - -/** - * Exception thrown by the {@link SLReturnNode return statement} and caught by the - * {@link SLFunctionBodyNode function body}. The exception transports the return value in its - * {@link #result} field. - */ -public final class SLReturnException extends ControlFlowException { - - private static final long serialVersionUID = 4073191346281369231L; - - private final Object result; - - public SLReturnException(Object result) { - this.result = result; - } - - public Object getResult() { - return result; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Implementation of the SL return statement. We need to unwind an unknown number of interpreter - * frames that are between this {@link SLReturnNode} and the {@link SLFunctionBodyNode} of the - * method we are exiting. This is done by throwing an {@link SLReturnException exception} that is - * caught by the {@link SLFunctionBodyNode#executeGeneric function body}. The exception transports - * the return value. - */ -@NodeInfo(shortName = "return", description = "The node implementing a return statement") -public final class SLReturnNode extends SLStatementNode { - - @Child private SLExpressionNode valueNode; - - public SLReturnNode(SourceSection src, SLExpressionNode valueNode) { - super(src); - this.valueNode = valueNode; - } - - @Override - public void executeVoid(VirtualFrame frame) { - Object result; - if (valueNode != null) { - result = valueNode.executeGeneric(frame); - } else { - /* Return statement that was not followed by an expression, so return the SL null value. */ - result = SLNull.SINGLETON; - } - throw new SLReturnException(result); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.controlflow; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -@NodeInfo(shortName = "while", description = "The node implementing a while loop") -public final class SLWhileNode extends SLStatementNode { - - @Child private LoopNode loopNode; - - public SLWhileNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode bodyNode) { - super(src); - this.loopNode = Truffle.getRuntime().createLoopNode(new SLRepeatingNode(src, conditionNode, bodyNode)); - } - - @Override - public void executeVoid(VirtualFrame frame) { - loopNode.executeLoop(frame); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * SL node that performs the "+" operation, which performs addition on arbitrary precision numbers, - * as well as String concatenation if one of the operands is a String. - *

- * Type specialization on the input values is essential for the performance. This is achieved via - * node rewriting: specialized subclasses handle just a single type, so that the generic node that - * can handle all types is used only in cases where different types were encountered. The subclasses - * are automatically generated by the Truffle DSL. In addition, a {@link SLAddNodeGen factory class} - * is generated that provides, e.g., {@link SLAddNodeGen#create node creation}. - */ -@NodeInfo(shortName = "+") -public abstract class SLAddNode extends SLBinaryNode { - - public SLAddNode(SourceSection src) { - super(src); - } - - /** - * Specialization for primitive {@code long} values. This is the fast path of the - * arbitrary-precision arithmetic. We need to check for overflows of the addition, and switch to - * the {@link #add(BigInteger, BigInteger) slow path}. Therefore, we use an - * {@link ExactMath#addExact(long, long) addition method that throws an exception on overflow}. - * The {@code rewriteOn} attribute on the {@link Specialization} annotation automatically - * triggers the node rewriting on the exception. - *

- * In compiled code, {@link ExactMath#addExact(long, long) addExact} is compiled to efficient - * machine code that uses the processor's overflow flag. Therefore, this method is compiled to - * only two machine code instructions on the fast path. - *

- * This specialization is automatically selected by the Truffle DSL if both the left and right - * operand are {@code long} values. - */ - @Specialization(rewriteOn = ArithmeticException.class) - protected long add(long left, long right) { - return ExactMath.addExact(left, right); - } - - /** - * This is the slow path of the arbitrary-precision arithmetic. The {@link BigInteger} type of - * Java is doing everything we need. - *

- * This specialization is automatically selected by the Truffle DSL if both the left and right - * operand are {@link BigInteger} values. Because the type system defines an - * {@link ImplicitCast implicit conversion} from {@code long} to {@link BigInteger} in - * {@link SLTypes#castBigInteger(long)}, this specialization is also taken if the left or the - * right operand is a {@code long} value. Because the {@link #add(long, long) long} - * specialization} has the {@code rewriteOn} attribute, this specialization is also taken if - * both input values are {@code long} values but the primitive addition overflows. - */ - @Specialization - @TruffleBoundary - protected BigInteger add(BigInteger left, BigInteger right) { - return left.add(right); - } - - /** - * Specialization for String concatenation. The SL specification says that String concatenation - * works if either the left or the right operand is a String. The non-string operand is - * converted then automatically converted to a String. - *

- * To implement these semantics, we tell the Truffle DSL to use a custom guard. The guard - * function is defined in {@link #isString this class}, but could also be in any superclass. - */ - @Specialization(guards = "isString(left, right)") - @TruffleBoundary - protected String add(Object left, Object right) { - return left.toString() + right.toString(); - } - - /** - * Guard for String concatenation: returns true if either the left or the right operand is a - * {@link String}. - */ - protected boolean isString(Object a, Object b) { - return a instanceof String || b instanceof String; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Constant literal for a arbitrary-precision number that exceeds the range of - * {@link SLLongLiteralNode}. - */ -@NodeInfo(shortName = "const") -public final class SLBigIntegerLiteralNode extends SLExpressionNode { - - private final BigInteger value; - - public SLBigIntegerLiteralNode(SourceSection src, BigInteger value) { - super(src); - this.value = value; - } - - @Override - public BigInteger executeGeneric(VirtualFrame frame) { - return value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the extensively documented {@link SLAddNode}. Divisions by 0 throw the - * same {@link ArithmeticException exception} as in Java, SL has no special handling for it to keep - * the code simple. - */ -@NodeInfo(shortName = "/") -public abstract class SLDivNode extends SLBinaryNode { - - public SLDivNode(SourceSection src) { - super(src); - } - - @Specialization(rewriteOn = ArithmeticException.class) - protected long div(long left, long right) throws ArithmeticException { - long result = left / right; - /* - * The division overflows if left is Long.MIN_VALUE and right is -1. - */ - if ((left & right & result) < 0) { - throw new ArithmeticException("long overflow"); - } - return result; - } - - @Specialization - protected BigInteger div(BigInteger left, BigInteger right) { - return left.divide(right); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * The {@code ==} operator of SL is defined on all types. Therefore, we need a - * {@link #equal(Object, Object) generic implementation} that can handle all possible types. But - * since {@code ==} can only return {@code true} when the type of the left and right operand are the - * same, the specializations already cover all possible cases that can return {@code true} and the - * generic case is trivial. - *

- * Note that we do not need the analogous {@code =!} operator, because we can just - * {@link SLLogicalNotNode negate} the {@code ==} operator. - */ -@NodeInfo(shortName = "==") -public abstract class SLEqualNode extends SLBinaryNode { - - public SLEqualNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - @Specialization - protected boolean equal(long left, long right) { - return left == right; - } - - @Specialization - protected boolean equal(BigInteger left, BigInteger right) { - return left.equals(right); - } - - @Specialization - protected boolean equal(boolean left, boolean right) { - return left == right; - } - - @Specialization - protected boolean equal(String left, String right) { - return left.equals(right); - } - - @Specialization - protected boolean equal(SLFunction left, SLFunction right) { - /* - * Our function registry maintains one canonical SLFunction object per function name, so we - * do not need equals(). - */ - return left == right; - } - - @Specialization - protected boolean equal(SLNull left, SLNull right) { - /* There is only the singleton instance of SLNull, so we do not need equals(). */ - return left == right; - } - - /** - * The {@link Fallback} annotation informs the Truffle DSL that this method should be executed - * when no {@link Specialization specialized method} matches. The operand types must be - * {@link Object}. - */ - @Fallback - protected boolean equal(Object left, Object right) { - /* - * We covered all the cases that can return true in specializations. If we compare two - * values with different types, no specialization matches and we end up here. - */ - assert !left.equals(right); - return false; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Constant literal for a {@link SLFunction function} value, created when a function name occurs as - * a literal in SL source code. Note that function redefinition can change the {@link CallTarget - * call target} that is executed when calling the function, but the {@link SLFunction} for a name - * never changes. This is guaranteed by the {@link SLFunctionRegistry}. - */ -@NodeInfo(shortName = "func") -public final class SLFunctionLiteralNode extends SLExpressionNode { - - private final SLFunction value; - - public SLFunctionLiteralNode(SourceSection src, SLFunction value) { - super(src); - this.value = value; - } - - @Override - public SLFunction executeGeneric(VirtualFrame frame) { - return value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the {@link SLLessThanNode}. - */ -@NodeInfo(shortName = "<=") -public abstract class SLLessOrEqualNode extends SLBinaryNode { - - public SLLessOrEqualNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - @Specialization - protected boolean lessOrEqual(long left, long right) { - return left <= right; - } - - @Specialization - protected boolean lessOrEqual(BigInteger left, BigInteger right) { - return left.compareTo(right) <= 0; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the extensively documented {@link SLAddNode}. The only difference: the - * specialized methods return {@code boolean} instead of the input types. - */ -@NodeInfo(shortName = "<") -public abstract class SLLessThanNode extends SLBinaryNode { - - public SLLessThanNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - @Specialization - protected boolean lessThan(long left, long right) { - return left < right; - } - - @Specialization - protected boolean lessThan(BigInteger left, BigInteger right) { - return left.compareTo(right) < 0; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class declares specializations similar to the extensively documented {@link SLAddNode}. It - * uses one additional feature of the Truffle DSL: {@link ShortCircuit}. - *

- * Logical operations in SL use short circuit evaluation: if the evaluation of the left operand - * already decides the result of the operation, the right operand must not be executed. This is - * expressed in the Truffle DSL via a method annotated with {@link ShortCircuit}, which returns - * whether a child needs to be executed based on the result of already executed children. - */ -@NodeInfo(shortName = "&&") -@SuppressWarnings("unused") -public abstract class SLLogicalAndNode extends SLBinaryNode { - - public SLLogicalAndNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - /** - * This method is called after the left child was evaluated, but before the right child is - * evaluated. The right child is only evaluated when the return value is {code true}. - */ - @ShortCircuit("rightNode") - protected boolean needsRightNode(boolean left) { - return left; - } - - /** - * Similar to {@link #needsRightNode(boolean)}, but for generic cases where the type of the left - * child is not known. - */ - @ShortCircuit("rightNode") - protected boolean needsRightNode(Object left) { - return left instanceof Boolean && needsRightNode(((Boolean) left).booleanValue()); - } - - @Specialization - protected boolean doBoolean(boolean left, boolean hasRight, boolean right) { - return left && right; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +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.sl.nodes.expression; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Example of a simple unary node that uses type specialization. See {@link SLAddNode} for - * information on specializations. - */ -@NodeChild("valueNode") -@NodeInfo(shortName = "!") -public abstract class SLLogicalNotNode extends SLExpressionNode { - - public SLLogicalNotNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - @Specialization - protected boolean doBoolean(boolean value) { - return !value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the {@link SLLogicalAndNode}. - */ -@NodeInfo(shortName = "||") -@SuppressWarnings("unused") -public abstract class SLLogicalOrNode extends SLBinaryNode { - - public SLLogicalOrNode(SourceSection src) { - super(src); - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - - @ShortCircuit("rightNode") - protected boolean needsRightNode(boolean left) { - return !left; - } - - @ShortCircuit("rightNode") - protected boolean needsRightNode(Object left) { - return left instanceof Boolean && needsRightNode(((Boolean) left).booleanValue()); - } - - @Specialization - protected boolean doBoolean(boolean left, boolean hasRight, boolean right) { - return left || right; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Constant literal for a primitive {@code long} value. The unboxed value can be returned when the - * parent expects a long value and calls {@link SLLongLiteralNode#executeLong}. In the generic case, - * the primitive value is automatically boxed by Java. - */ -@NodeInfo(shortName = "const") -public final class SLLongLiteralNode extends SLExpressionNode { - - private final long value; - - public SLLongLiteralNode(SourceSection src, long value) { - super(src); - this.value = value; - } - - @Override - public long executeLong(VirtualFrame frame) throws UnexpectedResultException { - return value; - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - return value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the extensively documented {@link SLAddNode}. - */ -@NodeInfo(shortName = "*") -public abstract class SLMulNode extends SLBinaryNode { - - public SLMulNode(SourceSection src) { - super(src); - } - - @Specialization(rewriteOn = ArithmeticException.class) - protected long mul(long left, long right) { - return ExactMath.multiplyExact(left, right); - } - - @Specialization - @TruffleBoundary - protected BigInteger mul(BigInteger left, BigInteger right) { - return left.multiply(right); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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.sl.nodes.expression; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * A {@link SLExpressionNode} that represents a parenthesized expression; it simply returns the - * value of the enclosed (child) expression. It is represented separately in the AST for the purpose - * of correct source attribution; this preserves the lexical relationship between the two - * parentheses and allows a tool to describe the expression as distinct from its contents. - */ -@NodeInfo(description = "A parenthesized expression") -public class SLParenExpressionNode extends SLExpressionNode { - - private final SLExpressionNode expression; - - public SLParenExpressionNode(SourceSection src, SLExpressionNode expression) { - super(src); - this.expression = insert(expression); - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - return expression.executeGeneric(frame); - } - - @Override - public long executeLong(VirtualFrame frame) throws UnexpectedResultException { - return expression.executeLong(frame); - } - - @Override - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - return expression.executeBoolean(frame); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Constant literal for a String value. - */ -@NodeInfo(shortName = "const") -public final class SLStringLiteralNode extends SLExpressionNode { - - private final String value; - - public SLStringLiteralNode(SourceSection src, String value) { - super(src); - this.value = value; - } - - @Override - public String executeGeneric(VirtualFrame frame) { - return value; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.expression; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * This class is similar to the extensively documented {@link SLAddNode}. - */ -@NodeInfo(shortName = "-") -public abstract class SLSubNode extends SLBinaryNode { - - public SLSubNode(SourceSection src) { - super(src); - } - - @Specialization(rewriteOn = ArithmeticException.class) - protected long sub(long left, long right) { - return ExactMath.subtractExact(left, right); - } - - @Specialization - protected BigInteger sub(BigInteger left, BigInteger right) { - return left.subtract(right); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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.sl.nodes.expression.demo; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.nodes.expression.*; - -/** - * This is an example how the add operation would be implemented without specializations and without - * the Truffle DSL. Do not write such code in your language! See {@link SLAddNode} how the add - * operation is implemented correctly. - */ -public class SLAddWithoutSpecializationNode extends SLExpressionNode { - - @Child private SLExpressionNode leftNode; - @Child private SLExpressionNode rightNode; - - public SLAddWithoutSpecializationNode(SLExpressionNode leftNode, SLExpressionNode rightNode) { - super(null); - this.leftNode = leftNode; - this.rightNode = rightNode; - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - /* Evaluate the child nodes. */ - Object left = leftNode.executeGeneric(frame); - Object right = rightNode.executeGeneric(frame); - - if (left instanceof Long && right instanceof Long) { - /* Fast path of the arbitrary-precision arithmetic. We need to check for overflows */ - try { - return ExactMath.addExact((Long) left, (Long) right); - } catch (ArithmeticException ex) { - /* Fall through to BigInteger case. */ - } - } - - /* Implicit type conversions. */ - if (left instanceof Long) { - left = BigInteger.valueOf((Long) left); - } - if (right instanceof Long) { - right = BigInteger.valueOf((Long) right); - } - if (left instanceof BigInteger && right instanceof BigInteger) { - /* Slow path of the arbitrary-precision arithmetic. */ - return ((BigInteger) left).add((BigInteger) right); - } - - /* String concatenation if either the left or the right operand is a String. */ - if (left instanceof String || right instanceof String) { - return left.toString() + right.toString(); - } - - /* Type error. */ - throw new UnsupportedSpecializationException(this, new Node[]{leftNode, rightNode}, new Object[]{left, right}); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLASTPrinter.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLASTPrinter.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.instrument; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; - -/** - * SLASTPrinter is used to print for SL's internal Truffle AST. This is used by - * {@link SLDefaultVisualizer} to provide a means of displaying the internal Truffle AST - */ -public final class SLASTPrinter extends DefaultASTPrinter { - - public SLASTPrinter() { - } - - @Override - protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { - if (node == null) { - p.print("null"); - return; - } - - p.print(nodeName(node)); - - p.print("("); - - if (node instanceof InstrumentationNode) { - p.print(instrumentInfo((InstrumentationNode) node)); - } - - p.print(sourceInfo(node)); - - p.print(NodeUtil.printSyntaxTags(node)); - - ArrayList childFields = new ArrayList<>(); - - for (NodeFieldAccessor field : NodeClass.get(node.getClass()).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { - childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { - // p.print(sep); - // sep = ", "; - // - // final String fieldName = field.getName(); - // switch (fieldName) { - // - // } - // p.print(fieldName); - // p.print(" = "); - // p.print(field.loadValue(node)); - } - } - p.print(")"); - - if (level <= maxDepth) { - - if (childFields.size() != 0) { - p.print(" {"); - for (NodeFieldAccessor field : childFields) { - - Object value = field.loadValue(node); - if (value == null) { - printNewLine(p, level); - p.print(field.getName()); - p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { - printChild(p, maxDepth, markNode, level, field, value); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - printChildren(p, maxDepth, markNode, level, field, value); - } else { - printNewLine(p, level); - p.print(field.getName()); - } - } - printNewLine(p, level - 1); - p.print("}"); - } - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +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.sl.nodes.instrument; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * SLDefaultVisualizer provides methods to get the names of SL's internal Truffle AST nodes. - * - */ -public class SLDefaultVisualizer extends DefaultVisualizer { - - private final SLASTPrinter astPrinter; - - public SLDefaultVisualizer() { - this.astPrinter = new SLASTPrinter(); - } - - @Override - public ASTPrinter getASTPrinter() { - return astPrinter; - } - - @Override - public String displayMethodName(Node node) { - - if (node == null) { - return null; - } - RootNode root = node.getRootNode(); - if (root instanceof SLRootNode) { - SLRootNode slRootNode = (SLRootNode) root; - return slRootNode.toString(); - - } - return "unknown"; - } - - @Override - public String displayCallTargetName(CallTarget callTarget) { - if (callTarget instanceof RootCallTarget) { - final RootCallTarget rootCallTarget = (RootCallTarget) callTarget; - SLRootNode slRootNode = (SLRootNode) rootCallTarget.getRootNode(); - return slRootNode.toString(); - } - return callTarget.toString(); - } - - @Override - public String displayValue(Object value, int trim) { - if (value == SLNull.SINGLETON) { - return "null"; - } - return trim(value.toString(), trim); - } - - @Override - public String displayIdentifier(FrameSlot slot) { - - final Object id = slot.getIdentifier(); - return id.toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /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.sl.nodes.instrument; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * A Truffle node that can be inserted into a Simple AST (assumed not to have executed yet) to - * enable "instrumentation" of an {@link SLExpressionNode}. Tools wishing to interact with AST - * execution may attach {@link Instrument}s to the {@link Probe} uniquely associated with the - * wrapper, and to which this wrapper routes execution events. - */ -@NodeInfo(cost = NodeCost.NONE) -public final class SLExpressionWrapperNode extends SLExpressionNode implements WrapperNode { - @Child private SLExpressionNode child; - @Child private ProbeNode probeNode; - - /** - * Constructor. - * - * @param child The {@link SLExpressionNode} that this wrapper is wrapping - */ - public SLExpressionWrapperNode(SLExpressionNode child) { - super(child.getSourceSection()); - assert !(child instanceof SLExpressionWrapperNode); - this.child = child; - } - - public String instrumentationInfo() { - return "Wrapper node for SL Expressions"; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public SLExpressionNode getNonWrapperNode() { - return child; - } - - public void insertProbe(ProbeNode newProbeNode) { - this.probeNode = newProbeNode; - } - - public Probe getProbe() { - return probeNode.getProbe(); - } - - public Node getChild() { - return child; - } - - @Override - public Object executeGeneric(VirtualFrame vFrame) { - - probeNode.enter(child, vFrame); - Object result; - - try { - result = child.executeGeneric(vFrame); - probeNode.returnValue(child, vFrame, result); - } catch (Exception e) { - probeNode.returnExceptional(child, vFrame, e); - throw (e); - } - return result; - } - - @Override - public long executeLong(VirtualFrame vFrame) throws UnexpectedResultException { - return SLTypesGen.expectLong(executeGeneric(vFrame)); - } - - @Override - public boolean executeBoolean(VirtualFrame vFrame) throws UnexpectedResultException { - return SLTypesGen.expectBoolean(executeGeneric(vFrame)); - } - - @Override - public SLFunction executeFunction(VirtualFrame vFrame) throws UnexpectedResultException { - probeNode.enter(child, vFrame); - SLFunction result; - - try { - result = child.executeFunction(vFrame); - probeNode.returnValue(child, vFrame, result); - } catch (Exception e) { - probeNode.returnExceptional(child, vFrame, e); - throw (e); - } - return result; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStandardASTProber.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStandardASTProber.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +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.sl.nodes.instrument; - -import static com.oracle.truffle.api.instrument.StandardSyntaxTag.*; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.nodes.controlflow.*; -import com.oracle.truffle.sl.nodes.local.*; - -/** - * A visitor which traverses a completely parsed Simple AST (presumed not yet executed) and enables - * instrumentation at a few standard kinds of nodes. - */ -public class SLStandardASTProber implements NodeVisitor, ASTProber { - - /** - * {@inheritDoc} - *

- * Instruments and tags all relevant {@link SLStatementNode}s and {@link SLExpressionNode}s. - * Currently, only SLStatementNodes that are not SLExpressionNodes are tagged as statements. - */ - public boolean visit(Node node) { - - if (!(node instanceof InstrumentationNode) && node instanceof SLStatementNode && node.getParent() != null && node.getSourceSection() != null) { - // All SL nodes are instrumentable, but treat expressions specially - - if (node instanceof SLExpressionNode) { - SLExpressionNode expressionNode = (SLExpressionNode) node; - Probe probe = expressionNode.probe(); - if (node instanceof SLWriteLocalVariableNode) { - probe.tagAs(STATEMENT, null); - probe.tagAs(ASSIGNMENT, null); - } - } else { - SLStatementNode statementNode = (SLStatementNode) node; - Probe probe = statementNode.probe(); - probe.tagAs(STATEMENT, null); - if (node instanceof SLWhileNode) { - probe.tagAs(START_LOOP, null); - } - } - } - return true; - } - - public void probeAST(Node node) { - node.accept(this); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +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.sl.nodes.instrument; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * A Truffle node that can be inserted into a Simple AST (assumed not to have executed yet) to - * enable "instrumentation" of a {@link SLStatementNode}. Tools wishing to interact with AST - * execution may attach {@link Instrument}s to the {@link Probe} uniquely associated with the - * wrapper, and to which this wrapper routes execution events. - */ -@NodeInfo(cost = NodeCost.NONE) -public final class SLStatementWrapperNode extends SLStatementNode implements WrapperNode { - - @Child private SLStatementNode child; - @Child private ProbeNode probeNode; - - public SLStatementWrapperNode(SLStatementNode child) { - super(child.getSourceSection()); - assert !(child instanceof SLStatementWrapperNode); - this.child = child; - } - - public String instrumentationInfo() { - return "Wrapper node for SL Statements"; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public SLStatementNode getNonWrapperNode() { - return child; - } - - public void insertProbe(ProbeNode newProbeNode) { - this.probeNode = newProbeNode; - } - - public Probe getProbe() { - return probeNode.getProbe(); - } - - @Override - public Node getChild() { - return child; - } - - @Override - public void executeVoid(VirtualFrame vFrame) { - probeNode.enter(child, vFrame); - - try { - child.executeVoid(vFrame); - probeNode.returnVoid(child, vFrame); - } catch (KillException e) { - throw (e); - } catch (Exception e) { - probeNode.returnExceptional(child, vFrame, e); - throw (e); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.local; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.parser.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Reads a function argument. Arguments are passed in as an object array. - *

- * Arguments are not type-specialized. To ensure that repeated accesses within a method are - * specialized and can, e.g., be accessed without unboxing, all arguments are loaded into local - * variables {@link SLNodeFactory#addFormalParameter in the method prologue}. - */ -public class SLReadArgumentNode extends SLExpressionNode { - - /** The argument number, i.e., the index into the array of arguments. */ - private final int index; - - /** - * Profiling information, collected by the interpreter, capturing whether the function was - * called with fewer actual arguments than formal arguments. - */ - private final BranchProfile outOfBoundsTaken = BranchProfile.create(); - - public SLReadArgumentNode(SourceSection src, int index) { - super(src); - this.index = index; - } - - @Override - public Object executeGeneric(VirtualFrame frame) { - Object[] args = frame.getArguments(); - if (index < args.length) { - return args[index]; - } else { - /* In the interpreter, record profiling information that the branch was used. */ - outOfBoundsTaken.enter(); - /* Use the default null value. */ - return SLNull.SINGLETON; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.local; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Node to read a local variable from a function's {@link VirtualFrame frame}. The Truffle frame API - * allows to store primitive values of all Java primitive types, and Object values. This means that - * all SL types that are objects are handled by the {@link #readObject} method. When a local - * variable changes its type, the frame access method throws an {@link FrameSlotTypeException}, - * which causes not rewriting. The rewriting code is generated by the Truffle DSL. - */ -@NodeField(name = "slot", type = FrameSlot.class) -public abstract class SLReadLocalVariableNode extends SLExpressionNode { - - public SLReadLocalVariableNode(SourceSection src) { - super(src); - } - - /** - * Returns the descriptor of the accessed local variable. The implementation of this method is - * created by the Truffle DSL based on the {@link NodeField} annotation on the class. - */ - protected abstract FrameSlot getSlot(); - - @Specialization(rewriteOn = FrameSlotTypeException.class) - protected long readLong(VirtualFrame frame) throws FrameSlotTypeException { - return frame.getLong(getSlot()); - } - - @Specialization(rewriteOn = FrameSlotTypeException.class) - protected boolean readBoolean(VirtualFrame frame) throws FrameSlotTypeException { - return frame.getBoolean(getSlot()); - } - - @Specialization(rewriteOn = FrameSlotTypeException.class) - protected Object readObject(VirtualFrame frame) throws FrameSlotTypeException { - return frame.getObject(getSlot()); - } - - /** - * This is the generic case that always succeeds. Since we already have another specialization - * with the same signature above, we need to order them explicitly with the order attribute. - */ - @Specialization(contains = {"readLong", "readBoolean", "readObject"}) - protected Object read(VirtualFrame frame) { - return frame.getValue(getSlot()); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.nodes.local; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Node to write a local variable to a function's {@link VirtualFrame frame}. The Truffle frame API - * allows to store primitive values of all Java primitive types, and Object values. - */ -@NodeChild("valueNode") -@NodeField(name = "slot", type = FrameSlot.class) -public abstract class SLWriteLocalVariableNode extends SLExpressionNode { - - public SLWriteLocalVariableNode(SourceSection src) { - super(src); - } - - /** - * Returns the descriptor of the accessed local variable. The implementation of this method is - * created by the Truffle DSL based on the {@link NodeField} annotation on the class. - */ - protected abstract FrameSlot getSlot(); - - /** - * Specialized method to write a primitive {@code long} value. This is only possible if the - * local variable also has currently the type {@code long}, therefore a Truffle DSL - * {@link #isLongKind(VirtualFrame) custom guard} is specified. - */ - @Specialization(guards = "isLongKind(frame)") - protected long writeLong(VirtualFrame frame, long value) { - frame.setLong(getSlot(), value); - return value; - } - - @Specialization(guards = "isBooleanKind(frame)") - protected boolean writeBoolean(VirtualFrame frame, boolean value) { - frame.setBoolean(getSlot(), value); - return value; - } - - /** - * Generic write method that works for all possible types. - *

- * Why is this method annotated with {@link Specialization} and not {@link Fallback}? For a - * {@link Fallback} method, the Truffle DSL generated code would try all other specializations - * first before calling this method. We know that all these specializations would fail their - * guards, so there is no point in calling them. Since this method takes a value of type - * {@link Object}, it is guaranteed to never fail, i.e., once we are in this specialization the - * node will never be re-specialized. - */ - @Specialization(contains = {"writeLong", "writeBoolean"}) - protected Object write(VirtualFrame frame, Object value) { - if (getSlot().getKind() != FrameSlotKind.Object) { - /* - * The local variable has still a primitive type, we need to change it to Object. Since - * the variable type is important when the compiler optimizes a method, we also discard - * compiled code. - */ - CompilerDirectives.transferToInterpreterAndInvalidate(); - getSlot().setKind(FrameSlotKind.Object); - } - frame.setObject(getSlot(), value); - return value; - } - - /** - * Guard function that the local variable has the type {@code long}. - */ - @SuppressWarnings("unused") - protected boolean isLongKind(VirtualFrame frame) { - return isKind(FrameSlotKind.Long); - } - - @SuppressWarnings("unused") - protected boolean isBooleanKind(VirtualFrame frame) { - return isKind(FrameSlotKind.Boolean); - } - - private boolean isKind(FrameSlotKind kind) { - if (getSlot().getKind() == kind) { - /* Success: the frame slot has the expected kind. */ - return true; - } else if (getSlot().getKind() == FrameSlotKind.Illegal) { - /* - * This is the first write to this local variable. We can set the type to the one we - * expect. Since the variable type is important when the compiler optimizes a method, we - * also discard compiled code. - */ - CompilerDirectives.transferToInterpreterAndInvalidate(); - getSlot().setKind(kind); - return true; - } else { - /* - * Failure: the frame slot has the wrong kind, the Truffle DSL generated code will - * choose a different specialization. - */ - return false; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -/*------------------------------------------------------------------------- -Compiler Generator Coco/R, -Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz -extended by M. Loeberbauer & A. Woess, Univ. of Linz -ported from C# to Java by Wolfgang Ahorner -with improvements by Pat Terry, Rhodes University - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program 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 -for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As an exception, it is allowed to write an extension of Coco/R that is -used as a plugin in non-free software. - -If not otherwise stated, any source code generated by Coco/R (other than -Coco/R itself) does not fall under the GNU General Public License. -------------------------------------------------------------------------*/ --->begin -package com.oracle.truffle.sl.parser; - -import java.util.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -// Checkstyle: stop -// @formatter:off -public class Parser { --->constants - static final boolean _T = true; - static final boolean _x = false; - static final int minErrDist = 2; - - public Token t; // last recognized token - public Token la; // lookahead token - int errDist = minErrDist; - - public final Scanner scanner; - public final Errors errors; - private final SLNodeFactory factory; - -->declarations - public Parser(SLContext context, Source source) { - this.scanner = new Scanner(source.getInputStream()); - this.factory = new SLNodeFactory(context, source); - errors = new Errors(); - } - - void SynErr(int n) { - if (errDist >= minErrDist) - errors.SynErr(la.line, la.col, n); - errDist = 0; - } - - public void SemErr(String msg) { - if (errDist >= minErrDist) - errors.SemErr(t.line, t.col, msg); - errDist = 0; - } - - void Get() { - for (;;) { - t = la; - la = scanner.Scan(); - if (la.kind <= maxT) { - ++errDist; - break; - } --->pragmas - la = t; - } - } - - void Expect(int n) { - if (la.kind == n) - Get(); - else { - SynErr(n); - } - } - - boolean StartOf(int s) { - return set[s][la.kind]; - } - - void ExpectWeak(int n, int follow) { - if (la.kind == n) - Get(); - else { - SynErr(n); - while (!StartOf(follow)) - Get(); - } - } - - boolean WeakSeparator(int n, int syFol, int repFol) { - int kind = la.kind; - if (kind == n) { - Get(); - return true; - } else if (StartOf(repFol)) - return false; - else { - SynErr(n); - while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) { - Get(); - kind = la.kind; - } - return StartOf(syFol); - } - } - --->productions - - public void Parse() { - la = new Token(); - la.val = ""; - Get(); --->parseRoot - } - - private static final boolean[][] set = { --->initialization - }; - - public static void parseSL(SLContext context, Source source) { - Parser parser = new Parser(context, source); - parser.Parse(); - if (parser.errors.errors.size() > 0) { - StringBuilder msg = new StringBuilder("Error(s) parsing script:\n"); - for (String error : parser.errors.errors) { - msg.append(error).append("\n"); - } - throw new SLException(msg.toString()); - } - } -} // end Parser - -class Errors { - - protected final List errors = new ArrayList<>(); - public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text - - protected void printMsg(int line, int column, String msg) { - StringBuffer b = new StringBuffer(errMsgFormat); - int pos = b.indexOf("{0}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, line); - } - pos = b.indexOf("{1}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, column); - } - pos = b.indexOf("{2}"); - if (pos >= 0) - b.replace(pos, pos + 3, msg); - errors.add(b.toString()); - } - - public void SynErr(int line, int col, int n) { - String s; - switch (n) {-->errors - default: - s = "error " + n; - break; - } - printMsg(line, col, s); - } - - public void SemErr(int line, int col, String s) { - printMsg(line, col, s); - } - - public void SemErr(String s) { - errors.add(s); - } - - public void Warning(int line, int col, String s) { - printMsg(line, col, s); - } - - public void Warning(String s) { - errors.add(s); - } -} // Errors - -class FatalError extends RuntimeException { - - public static final long serialVersionUID = 1L; - - public FatalError(String s) { - super(s); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,546 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. - -package com.oracle.truffle.sl.parser; - -import java.util.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.runtime.*; - -// Checkstyle: stop -// @formatter:off -public class Parser { - public static final int _EOF = 0; - public static final int _identifier = 1; - public static final int _stringLiteral = 2; - public static final int _numericLiteral = 3; - public static final int maxT = 31; - - static final boolean _T = true; - static final boolean _x = false; - static final int minErrDist = 2; - - public Token t; // last recognized token - public Token la; // lookahead token - int errDist = minErrDist; - - public final Scanner scanner; - public final Errors errors; - private final SLNodeFactory factory; - - public Parser(SLContext context, Source source) { - this.scanner = new Scanner(source.getInputStream()); - this.factory = new SLNodeFactory(context, source); - errors = new Errors(); - } - - void SynErr(int n) { - if (errDist >= minErrDist) - errors.SynErr(la.line, la.col, n); - errDist = 0; - } - - public void SemErr(String msg) { - if (errDist >= minErrDist) - errors.SemErr(t.line, t.col, msg); - errDist = 0; - } - - void Get() { - for (;;) { - t = la; - la = scanner.Scan(); - if (la.kind <= maxT) { - ++errDist; - break; - } - - la = t; - } - } - - void Expect(int n) { - if (la.kind == n) - Get(); - else { - SynErr(n); - } - } - - boolean StartOf(int s) { - return set[s][la.kind]; - } - - void ExpectWeak(int n, int follow) { - if (la.kind == n) - Get(); - else { - SynErr(n); - while (!StartOf(follow)) - Get(); - } - } - - boolean WeakSeparator(int n, int syFol, int repFol) { - int kind = la.kind; - if (kind == n) { - Get(); - return true; - } else if (StartOf(repFol)) - return false; - else { - SynErr(n); - while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) { - Get(); - kind = la.kind; - } - return StartOf(syFol); - } - } - - void SimpleLanguage() { - Function(); - while (la.kind == 4) { - Function(); - } - } - - void Function() { - Expect(4); - Expect(1); - Token identifierToken = t; - Expect(5); - int bodyStartPos = t.charPos; - factory.startFunction(identifierToken, bodyStartPos); - if (la.kind == 1) { - Get(); - factory.addFormalParameter(t); - while (la.kind == 6) { - Get(); - Expect(1); - factory.addFormalParameter(t); - } - } - Expect(7); - SLStatementNode body = Block(false); - factory.finishFunction(body); - } - - SLStatementNode Block(boolean inLoop) { - SLStatementNode result; - factory.startBlock(); - List body = new ArrayList<>(); - Expect(8); - int start = t.charPos; - while (StartOf(1)) { - SLStatementNode s = Statement(inLoop); - body.add(s); - } - Expect(9); - int length = (t.charPos + t.val.length()) - start; - result = factory.finishBlock(body, start, length); - return result; - } - - SLStatementNode Statement(boolean inLoop) { - SLStatementNode result; - result = null; - switch (la.kind) { - case 13: { - result = WhileStatement(); - break; - } - case 10: { - Get(); - if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } - Expect(11); - break; - } - case 12: { - Get(); - if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } - Expect(11); - break; - } - case 14: { - result = IfStatement(inLoop); - break; - } - case 16: { - result = ReturnStatement(); - break; - } - case 1: case 2: case 3: case 5: { - result = Expression(); - Expect(11); - break; - } - default: SynErr(32); break; - } - return result; - } - - SLStatementNode WhileStatement() { - SLStatementNode result; - Expect(13); - Token whileToken = t; - Expect(5); - SLExpressionNode condition = Expression(); - Expect(7); - SLStatementNode body = Block(true); - result = factory.createWhile(whileToken, condition, body); - return result; - } - - SLStatementNode IfStatement(boolean inLoop) { - SLStatementNode result; - Expect(14); - Token ifToken = t; - Expect(5); - SLExpressionNode condition = Expression(); - Expect(7); - SLStatementNode thenPart = Block(inLoop); - SLStatementNode elsePart = null; - if (la.kind == 15) { - Get(); - elsePart = Block(inLoop); - } - result = factory.createIf(ifToken, condition, thenPart, elsePart); - return result; - } - - SLStatementNode ReturnStatement() { - SLStatementNode result; - Expect(16); - Token returnToken = t; - SLExpressionNode value = null; - if (StartOf(2)) { - value = Expression(); - } - result = factory.createReturn(returnToken, value); - Expect(11); - return result; - } - - SLExpressionNode Expression() { - SLExpressionNode result; - result = LogicTerm(); - while (la.kind == 17) { - Get(); - Token op = t; - SLExpressionNode right = LogicTerm(); - result = factory.createBinary(op, result, right); - } - return result; - } - - SLExpressionNode LogicTerm() { - SLExpressionNode result; - result = LogicFactor(); - while (la.kind == 18) { - Get(); - Token op = t; - SLExpressionNode right = LogicFactor(); - result = factory.createBinary(op, result, right); - } - return result; - } - - SLExpressionNode LogicFactor() { - SLExpressionNode result; - result = Arithmetic(); - if (StartOf(3)) { - switch (la.kind) { - case 19: { - Get(); - break; - } - case 20: { - Get(); - break; - } - case 21: { - Get(); - break; - } - case 22: { - Get(); - break; - } - case 23: { - Get(); - break; - } - case 24: { - Get(); - break; - } - } - Token op = t; - SLExpressionNode right = Arithmetic(); - result = factory.createBinary(op, result, right); - } - return result; - } - - SLExpressionNode Arithmetic() { - SLExpressionNode result; - result = Term(); - while (la.kind == 25 || la.kind == 26) { - if (la.kind == 25) { - Get(); - } else { - Get(); - } - Token op = t; - SLExpressionNode right = Term(); - result = factory.createBinary(op, result, right); - } - return result; - } - - SLExpressionNode Term() { - SLExpressionNode result; - result = Factor(); - while (la.kind == 27 || la.kind == 28) { - if (la.kind == 27) { - Get(); - } else { - Get(); - } - Token op = t; - SLExpressionNode right = Factor(); - result = factory.createBinary(op, result, right); - } - return result; - } - - SLExpressionNode Factor() { - SLExpressionNode result; - result = null; - if (la.kind == 1) { - Get(); - if (la.kind == 5 || la.kind == 29 || la.kind == 30) { - result = MemberExpression(null, null, t); - } else if (StartOf(4)) { - result = factory.createRead(t); - } else SynErr(33); - } else if (la.kind == 2) { - Get(); - result = factory.createStringLiteral(t); - } else if (la.kind == 3) { - Get(); - result = factory.createNumericLiteral(t); - } else if (la.kind == 5) { - Get(); - int start = t.charPos; - result = Expression(); - SLExpressionNode expr = result; - Expect(7); - int length = (t.charPos + t.val.length()) - start; - result = factory.createParenExpression(expr, start, length); - } else SynErr(34); - return result; - } - - SLExpressionNode MemberExpression(SLExpressionNode r, SLExpressionNode assignmentReceiver, Token assignmentName) { - SLExpressionNode result; - result = null; - SLExpressionNode receiver = r; - Token nestedAssignmentName = null; - if (la.kind == 5) { - Get(); - List parameters = new ArrayList<>(); - SLExpressionNode parameter; - if (receiver == null) { - receiver = factory.createRead(assignmentName); - } - if (StartOf(2)) { - parameter = Expression(); - parameters.add(parameter); - while (la.kind == 6) { - Get(); - parameter = Expression(); - parameters.add(parameter); - } - } - Expect(7); - Token finalToken = t; - result = factory.createCall(receiver, parameters, finalToken); - } else if (la.kind == 29) { - Get(); - SLExpressionNode value = Expression(); - if (assignmentName == null) { - SemErr("invalid assignment target"); - } else if (assignmentReceiver == null) { - result = factory.createAssignment(assignmentName, value); - } else { - result = factory.createWriteProperty(assignmentReceiver, assignmentName, value); - } - } else if (la.kind == 30) { - Get(); - if (receiver == null) { - receiver = factory.createRead(assignmentName); - } - Expect(1); - result = factory.createReadProperty(receiver, t); - nestedAssignmentName = t; - } else SynErr(35); - if (la.kind == 5 || la.kind == 29 || la.kind == 30) { - result = MemberExpression(result, receiver, nestedAssignmentName); - } - return result; - } - - - - public void Parse() { - la = new Token(); - la.val = ""; - Get(); - SimpleLanguage(); - Expect(0); - - } - - private static final boolean[][] set = { - {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x}, - {_x,_T,_T,_T, _x,_T,_x,_x, _x,_x,_T,_x, _T,_T,_T,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x}, - {_x,_T,_T,_T, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x}, - {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x}, - {_x,_x,_x,_x, _x,_T,_T,_T, _x,_x,_x,_T, _x,_x,_x,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _x} - - }; - - public static void parseSL(SLContext context, Source source) { - Parser parser = new Parser(context, source); - parser.Parse(); - if (parser.errors.errors.size() > 0) { - StringBuilder msg = new StringBuilder("Error(s) parsing script:\n"); - for (String error : parser.errors.errors) { - msg.append(error).append("\n"); - } - throw new SLException(msg.toString()); - } - } -} // end Parser - -class Errors { - - protected final List errors = new ArrayList<>(); - public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text - - protected void printMsg(int line, int column, String msg) { - StringBuffer b = new StringBuffer(errMsgFormat); - int pos = b.indexOf("{0}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, line); - } - pos = b.indexOf("{1}"); - if (pos >= 0) { - b.delete(pos, pos + 3); - b.insert(pos, column); - } - pos = b.indexOf("{2}"); - if (pos >= 0) - b.replace(pos, pos + 3, msg); - errors.add(b.toString()); - } - - public void SynErr(int line, int col, int n) { - String s; - switch (n) { - case 0: s = "EOF expected"; break; - case 1: s = "identifier expected"; break; - case 2: s = "stringLiteral expected"; break; - case 3: s = "numericLiteral expected"; break; - case 4: s = "\"function\" expected"; break; - case 5: s = "\"(\" expected"; break; - case 6: s = "\",\" expected"; break; - case 7: s = "\")\" expected"; break; - case 8: s = "\"{\" expected"; break; - case 9: s = "\"}\" expected"; break; - case 10: s = "\"break\" expected"; break; - case 11: s = "\";\" expected"; break; - case 12: s = "\"continue\" expected"; break; - case 13: s = "\"while\" expected"; break; - case 14: s = "\"if\" expected"; break; - case 15: s = "\"else\" expected"; break; - case 16: s = "\"return\" expected"; break; - case 17: s = "\"||\" expected"; break; - case 18: s = "\"&&\" expected"; break; - case 19: s = "\"<\" expected"; break; - case 20: s = "\"<=\" expected"; break; - case 21: s = "\">\" expected"; break; - case 22: s = "\">=\" expected"; break; - case 23: s = "\"==\" expected"; break; - case 24: s = "\"!=\" expected"; break; - case 25: s = "\"+\" expected"; break; - case 26: s = "\"-\" expected"; break; - case 27: s = "\"*\" expected"; break; - case 28: s = "\"/\" expected"; break; - case 29: s = "\"=\" expected"; break; - case 30: s = "\".\" expected"; break; - case 31: s = "??? expected"; break; - case 32: s = "invalid Statement"; break; - case 33: s = "invalid Factor"; break; - case 34: s = "invalid Factor"; break; - case 35: s = "invalid MemberExpression"; break; - default: - s = "error " + n; - break; - } - printMsg(line, col, s); - } - - public void SemErr(int line, int col, String s) { - printMsg(line, col, s); - } - - public void SemErr(String s) { - errors.add(s); - } - - public void Warning(int line, int col, String s) { - printMsg(line, col, s); - } - - public void Warning(String s) { - errors.add(s); - } -} // Errors - -class FatalError extends RuntimeException { - - public static final long serialVersionUID = 1L; - - public FatalError(String s) { - super(s); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.parser; - -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.nodes.access.*; -import com.oracle.truffle.sl.nodes.call.*; -import com.oracle.truffle.sl.nodes.controlflow.*; -import com.oracle.truffle.sl.nodes.expression.*; -import com.oracle.truffle.sl.nodes.local.*; -import com.oracle.truffle.sl.runtime.*; - -/** - * Helper class used by the SL {@link Parser} to create nodes. The code is factored out of the - * automatically generated parser to keep the attributed grammar of SL small. - */ -public class SLNodeFactory { - - /** - * Local variable names that are visible in the current block. Variables are not visible outside - * of their defining block, to prevent the usage of undefined variables. Because of that, we can - * decide during parsing if a name references a local variable or is a function name. - */ - static class LexicalScope { - protected final LexicalScope outer; - protected final Map locals; - - public LexicalScope(LexicalScope outer) { - this.outer = outer; - this.locals = new HashMap<>(); - if (outer != null) { - locals.putAll(outer.locals); - } - } - } - - /* State while parsing a source unit. */ - private final SLContext context; - private final Source source; - - /* State while parsing a function. */ - private int functionStartPos; - private String functionName; - private int functionBodyStartPos; // includes parameter list - private int parameterCount; - private FrameDescriptor frameDescriptor; - private List methodNodes; - - /* State while parsing a block. */ - private LexicalScope lexicalScope; - - public SLNodeFactory(SLContext context, Source source) { - this.context = context; - this.source = source; - } - - public void startFunction(Token nameToken, int bodyStartPos) { - assert functionStartPos == 0; - assert functionName == null; - assert functionBodyStartPos == 0; - assert parameterCount == 0; - assert frameDescriptor == null; - assert lexicalScope == null; - - functionStartPos = nameToken.charPos; - functionName = nameToken.val; - functionBodyStartPos = bodyStartPos; - frameDescriptor = new FrameDescriptor(); - methodNodes = new ArrayList<>(); - startBlock(); - } - - public void addFormalParameter(Token nameToken) { - /* - * Method parameters are assigned to local variables at the beginning of the method. This - * ensures that accesses to parameters are specialized the same way as local variables are - * specialized. - */ - final SourceSection src = srcFromToken(nameToken); - final SLReadArgumentNode readArg = new SLReadArgumentNode(src, parameterCount); - methodNodes.add(createAssignment(nameToken, readArg)); - parameterCount++; - } - - public void finishFunction(SLStatementNode bodyNode) { - methodNodes.add(bodyNode); - final int bodyEndPos = bodyNode.getSourceSection().getCharEndIndex(); - final SourceSection functionSrc = source.createSection(functionName, functionStartPos, bodyEndPos - functionStartPos); - final SLStatementNode methodBlock = finishBlock(methodNodes, functionBodyStartPos, bodyEndPos - functionBodyStartPos); - assert lexicalScope == null : "Wrong scoping of blocks in parser"; - - final SLFunctionBodyNode functionBodyNode = new SLFunctionBodyNode(functionSrc, methodBlock); - final SLRootNode rootNode = new SLRootNode(this.context, frameDescriptor, functionBodyNode, functionName); - rootNode.assignSourceSection(functionSrc); - - context.getFunctionRegistry().register(functionName, rootNode); - - functionStartPos = 0; - functionName = null; - functionBodyStartPos = 0; - parameterCount = 0; - frameDescriptor = null; - lexicalScope = null; - } - - public void startBlock() { - lexicalScope = new LexicalScope(lexicalScope); - } - - public SLStatementNode finishBlock(List bodyNodes, int startPos, int length) { - lexicalScope = lexicalScope.outer; - - List flattenedNodes = new ArrayList<>(bodyNodes.size()); - flattenBlocks(bodyNodes, flattenedNodes); - - final SourceSection src = source.createSection("block", startPos, length); - return new SLBlockNode(src, flattenedNodes.toArray(new SLStatementNode[flattenedNodes.size()])); - } - - private void flattenBlocks(Iterable bodyNodes, List flattenedNodes) { - for (Node n : bodyNodes) { - if (n instanceof SLBlockNode) { - flattenBlocks(n.getChildren(), flattenedNodes); - } else { - flattenedNodes.add((SLStatementNode) n); - } - } - } - - /** - * Returns an {@link SLBreakNode} for the given token. - * - * @param breakToken The token containing the break node's info. - * @return A SLBreakNode for the given token. - */ - public SLStatementNode createBreak(Token breakToken) { - final SLBreakNode breakNode = new SLBreakNode(srcFromToken(breakToken)); - return breakNode; - } - - /** - * Returns an {@link SLContinueNode} for the given token. - * - * @param continueToken The token containing the continue node's info. - * @return A SLContinueNode built using the given token. - */ - public SLStatementNode createContinue(Token continueToken) { - final SLContinueNode continueNode = new SLContinueNode(srcFromToken(continueToken)); - return continueNode; - } - - /** - * Returns an {@link SLWhileNode} for the given parameters. - * - * @param whileToken The token containing the while node's info - * @param conditionNode The conditional node for this while loop - * @param bodyNode The body of the while loop - * @return A SLWhileNode built using the given parameters. - */ - public SLStatementNode createWhile(Token whileToken, SLExpressionNode conditionNode, SLStatementNode bodyNode) { - final int start = whileToken.charPos; - final int end = bodyNode.getSourceSection().getCharEndIndex(); - final SLWhileNode whileNode = new SLWhileNode(source.createSection(whileToken.val, start, end - start), conditionNode, bodyNode); - return whileNode; - } - - /** - * Returns an {@link SLIfNode} for the given parameters. - * - * @param ifToken The token containing the if node's info - * @param conditionNode The condition node of this if statement - * @param thenPartNode The then part of the if - * @param elsePartNode The else part of the if - * @return An SLIfNode for the given parameters. - */ - public SLStatementNode createIf(Token ifToken, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { - final int start = ifToken.charPos; - final int end = elsePartNode == null ? thenPartNode.getSourceSection().getCharEndIndex() : elsePartNode.getSourceSection().getCharEndIndex(); - final SLIfNode ifNode = new SLIfNode(source.createSection(ifToken.val, start, end - start), conditionNode, thenPartNode, elsePartNode); - return ifNode; - } - - /** - * Returns an {@link SLReturnNode} for the given parameters. - * - * @param t The token containing the return node's info - * @param valueNode The value of the return - * @return An SLReturnNode for the given parameters. - */ - public SLStatementNode createReturn(Token t, SLExpressionNode valueNode) { - final int start = t.charPos; - final int length = valueNode == null ? t.val.length() : valueNode.getSourceSection().getCharEndIndex() - start; - final SLReturnNode returnNode = new SLReturnNode(source.createSection(t.val, start, length), valueNode); - return returnNode; - } - - /** - * Returns the corresponding subclass of {@link SLExpressionNode} for binary expressions. - *
These nodes are currently not instrumented. - * - * @param opToken The operator of the binary expression - * @param leftNode The left node of the expression - * @param rightNode The right node of the expression - * @return A subclass of SLExpressionNode using the given parameters based on the given opToken. - */ - public SLExpressionNode createBinary(Token opToken, SLExpressionNode leftNode, SLExpressionNode rightNode) { - int start = leftNode.getSourceSection().getCharIndex(); - int length = rightNode.getSourceSection().getCharEndIndex() - start; - final SourceSection src = source.createSection(opToken.val, start, length); - switch (opToken.val) { - case "+": - return SLAddNodeGen.create(src, leftNode, rightNode); - case "*": - return SLMulNodeGen.create(src, leftNode, rightNode); - case "/": - return SLDivNodeGen.create(src, leftNode, rightNode); - case "-": - return SLSubNodeGen.create(src, leftNode, rightNode); - case "<": - return SLLessThanNodeGen.create(src, leftNode, rightNode); - case "<=": - return SLLessOrEqualNodeGen.create(src, leftNode, rightNode); - case ">": - return SLLogicalNotNodeGen.create(src, SLLessOrEqualNodeGen.create(null, leftNode, rightNode)); - case ">=": - return SLLogicalNotNodeGen.create(src, SLLessThanNodeGen.create(null, leftNode, rightNode)); - case "==": - return SLEqualNodeGen.create(src, leftNode, rightNode); - case "!=": - return SLLogicalNotNodeGen.create(src, SLEqualNodeGen.create(null, leftNode, rightNode)); - case "&&": - return SLLogicalAndNodeGen.create(src, leftNode, rightNode); - case "||": - return SLLogicalOrNodeGen.create(src, leftNode, rightNode); - default: - throw new RuntimeException("unexpected operation: " + opToken.val); - } - } - - /** - * Returns an {@link SLInvokeNode} for the given parameters. - * - * @param functionNode The function being called - * @param parameterNodes The parameters of the function call - * @param finalToken A token used to determine the end of the sourceSelection for this call - * @return An SLInvokeNode for the given parameters. - */ - public SLExpressionNode createCall(SLExpressionNode functionNode, List parameterNodes, Token finalToken) { - final int startPos = functionNode.getSourceSection().getCharIndex(); - final int endPos = finalToken.charPos + finalToken.val.length(); - final SourceSection src = source.createSection(functionNode.getSourceSection().getIdentifier(), startPos, endPos - startPos); - return SLInvokeNode.create(src, functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()])); - } - - /** - * Returns an {@link SLWriteLocalVariableNode} for the given parameters. - * - * @param nameToken The name of the variable being assigned - * @param valueNode The value to be assigned - * @return An SLExpressionNode for the given parameters. - */ - public SLExpressionNode createAssignment(Token nameToken, SLExpressionNode valueNode) { - FrameSlot frameSlot = frameDescriptor.findOrAddFrameSlot(nameToken.val); - lexicalScope.locals.put(nameToken.val, frameSlot); - final int start = nameToken.charPos; - final int length = valueNode.getSourceSection().getCharEndIndex() - start; - return SLWriteLocalVariableNodeGen.create(source.createSection("=", start, length), valueNode, frameSlot); - } - - /** - * Returns a {@link SLReadLocalVariableNode} if this read is a local variable or a - * {@link SLFunctionLiteralNode} if this read is global. In Simple, the only global names are - * functions.
There is currently no instrumentation for this node. - * - * @param nameToken The name of the variable/function being read - * @return either: - *

    - *
  • A SLReadLocalVariableNode representing the local variable being read.
  • - *
  • A SLFunctionLiteralNode representing the function definition
  • - *
- */ - public SLExpressionNode createRead(Token nameToken) { - final FrameSlot frameSlot = lexicalScope.locals.get(nameToken.val); - final SourceSection src = srcFromToken(nameToken); - if (frameSlot != null) { - /* Read of a local variable. */ - return SLReadLocalVariableNodeGen.create(src, frameSlot); - } else { - /* Read of a global name. In our language, the only global names are functions. */ - return new SLFunctionLiteralNode(src, context.getFunctionRegistry().lookup(nameToken.val)); - } - } - - public SLExpressionNode createStringLiteral(Token literalToken) { - /* Remove the trailing and ending " */ - String literal = literalToken.val; - assert literal.length() >= 2 && literal.startsWith("\"") && literal.endsWith("\""); - final SourceSection src = srcFromToken(literalToken); - literal = literal.substring(1, literal.length() - 1); - - return new SLStringLiteralNode(src, literal); - } - - public SLExpressionNode createNumericLiteral(Token literalToken) { - final SourceSection src = srcFromToken(literalToken); - try { - /* Try if the literal is small enough to fit into a long value. */ - return new SLLongLiteralNode(src, Long.parseLong(literalToken.val)); - } catch (NumberFormatException ex) { - /* Overflow of long value, so fall back to BigInteger. */ - return new SLBigIntegerLiteralNode(src, new BigInteger(literalToken.val)); - } - } - - public SLExpressionNode createParenExpression(SLExpressionNode expressionNode, int start, int length) { - final SourceSection src = source.createSection("()", start, length); - return new SLParenExpressionNode(src, expressionNode); - } - - /** - * Returns an {@link SLReadPropertyNode} for the given parameters. - * - * @param receiverNode The receiver of the property access - * @param nameToken The name of the property being accessed - * @return An SLExpressionNode for the given parameters. - */ - public SLExpressionNode createReadProperty(SLExpressionNode receiverNode, Token nameToken) { - final int startPos = receiverNode.getSourceSection().getCharIndex(); - final int endPos = nameToken.charPos + nameToken.val.length(); - final SourceSection src = source.createSection(".", startPos, endPos - startPos); - return SLReadPropertyNode.create(src, receiverNode, nameToken.val); - } - - /** - * Returns an {@link SLWritePropertyNode} for the given parameters. - * - * @param receiverNode The receiver object of the property assignment - * @param nameToken The name of the property being assigned - * @param valueNode The value to be assigned - * @return An SLExpressionNode for the given parameters. - */ - public SLExpressionNode createWriteProperty(SLExpressionNode receiverNode, Token nameToken, SLExpressionNode valueNode) { - final int start = receiverNode.getSourceSection().getCharIndex(); - final int length = valueNode.getSourceSection().getCharEndIndex() - start; - SourceSection src = source.createSection("=", start, length); - return SLWritePropertyNode.create(src, receiverNode, nameToken.val, valueNode); - } - - /** - * Creates source description of a single token. - */ - private SourceSection srcFromToken(Token token) { - return source.createSection(token.val, token.charPos, token.val.length()); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.frame Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,515 +0,0 @@ -/*------------------------------------------------------------------------- -Compiler Generator Coco/R, -Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz -extended by M. Loeberbauer & A. Woess, Univ. of Linz -ported from C# to Java by Wolfgang Ahorner -with improvements by Pat Terry, Rhodes University - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program 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 -for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As an exception, it is allowed to write an extension of Coco/R that is -used as a plugin in non-free software. - -If not otherwise stated, any source code generated by Coco/R (other than -Coco/R itself) does not fall under the GNU General Public License. -------------------------------------------------------------------------*/ --->begin -package com.oracle.truffle.sl.parser; - -import java.io.InputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Map; -import java.util.HashMap; - -// Checkstyle: stop -// @formatter:off -class Token { - - public int kind; // token kind - public int pos; // token position in bytes in the source text (starting at 0) - public int charPos; // token position in characters in the source text (starting at 0) - public int col; // token column (starting at 1) - public int line; // token line (starting at 1) - public String val; // token value - public Token next; // ML 2005-03-11 Peek tokens are kept in linked list -} - -// ----------------------------------------------------------------------------------- -// Buffer -// ----------------------------------------------------------------------------------- -class Buffer { - - // This Buffer supports the following cases: - // 1) seekable stream (file) - // a) whole stream in buffer - // b) part of stream in buffer - // 2) non seekable stream (network, console) - - public static final int EOF = Character.MAX_VALUE + 1; - private static final int MIN_BUFFER_LENGTH = 1024; // 1KB - private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB - private byte[] buf; // input buffer - private int bufStart; // position of first byte in buffer relative to input stream - private int bufLen; // length of buffer - private int fileLen; // length of input stream (may change if stream is no file) - private int bufPos; // current position in buffer - private RandomAccessFile file; // input stream (seekable) - private InputStream stream; // growing input stream (e.g.: console, network) - - public Buffer(InputStream s) { - stream = s; - fileLen = bufLen = bufStart = bufPos = 0; - buf = new byte[MIN_BUFFER_LENGTH]; - } - - public Buffer(String fileName) { - try { - file = new RandomAccessFile(fileName, "r"); - fileLen = (int) file.length(); - bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH); - buf = new byte[bufLen]; - bufStart = Integer.MAX_VALUE; // nothing in buffer so far - if (fileLen > 0) - setPos(0); // setup buffer to position 0 (start) - else - bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid - if (bufLen == fileLen) - Close(); - } catch (IOException e) { - throw new FatalError("Could not open file " + fileName); - } - } - - // don't use b after this call anymore - // called in UTF8Buffer constructor - protected Buffer(Buffer b) { - buf = b.buf; - bufStart = b.bufStart; - bufLen = b.bufLen; - fileLen = b.fileLen; - bufPos = b.bufPos; - file = b.file; - stream = b.stream; - // keep finalize from closing the file - b.file = null; - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - Close(); - } - - protected void Close() { - if (file != null) { - try { - file.close(); - file = null; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } - } - - public int Read() { - if (bufPos < bufLen) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (getPos() < fileLen) { - setPos(getPos()); // shift buffer start to pos - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (stream != null && ReadNextStreamChunk() > 0) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else { - return EOF; - } - } - - public int Peek() { - int curPos = getPos(); - int ch = Read(); - setPos(curPos); - return ch; - } - - // beg .. begin, zero-based, inclusive, in byte - // end .. end, zero-based, exclusive, in byte - public String GetString(int beg, int end) { - int len = 0; - char[] buffer = new char[end - beg]; - int oldPos = getPos(); - setPos(beg); - while (getPos() < end) - buffer[len++] = (char) Read(); - setPos(oldPos); - return new String(buffer, 0, len); - } - - public int getPos() { - return bufPos + bufStart; - } - - public void setPos(int value) { - if (value >= fileLen && stream != null) { - // Wanted position is after buffer and the stream - // is not seek-able e.g. network or console, - // thus we have to read the stream manually till - // the wanted position is in sight. - while (value >= fileLen && ReadNextStreamChunk() > 0) { - // nothing to do... - } - } - - if (value < 0 || value > fileLen) { - throw new FatalError("buffer out of bounds access, position: " + value); - } - - if (value >= bufStart && value < bufStart + bufLen) { // already in buffer - bufPos = value - bufStart; - } else if (file != null) { // must be swapped in - try { - file.seek(value); - bufLen = file.read(buf); - bufStart = value; - bufPos = 0; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } else { - // set the position to the end of the file, Pos will return fileLen. - bufPos = fileLen - bufStart; - } - } - - // Read the next chunk of bytes from the stream, increases the buffer - // if needed and updates the fields fileLen and bufLen. - // Returns the number of bytes read. - private int ReadNextStreamChunk() { - int free = buf.length - bufLen; - if (free == 0) { - // in the case of a growing input stream - // we can neither seek in the stream, nor can we - // foresee the maximum length, thus we must adapt - // the buffer size on demand. - byte[] newBuf = new byte[bufLen * 2]; - System.arraycopy(buf, 0, newBuf, 0, bufLen); - buf = newBuf; - free = bufLen; - } - - int read; - try { - read = stream.read(buf, bufLen, free); - } catch (IOException ioex) { - throw new FatalError(ioex.getMessage()); - } - - if (read > 0) { - fileLen = bufLen = (bufLen + read); - return read; - } - // end of stream reached - return 0; - } -} - -// ----------------------------------------------------------------------------------- -// UTF8Buffer -// ----------------------------------------------------------------------------------- -class UTF8Buffer extends Buffer { - - UTF8Buffer(Buffer b) { - super(b); - } - - @Override - public int Read() { - int ch; - do { - ch = super.Read(); - // until we find a utf8 start (0xxxxxxx or 11xxxxxx) - } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF)); - if (ch < 128 || ch == EOF) { - // nothing to do, first 127 chars are the same in ascii and utf8 - // 0xxxxxxx or end of file character - } else if ((ch & 0xF0) == 0xF0) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x07; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = super.Read(); - int c4 = ch & 0x3F; - ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4; - } else if ((ch & 0xE0) == 0xE0) { - // 1110xxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x0F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = (((c1 << 6) | c2) << 6) | c3; - } else if ((ch & 0xC0) == 0xC0) { - // 110xxxxx 10xxxxxx - int c1 = ch & 0x1F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = (c1 << 6) | c2; - } - return ch; - } -} - -// ----------------------------------------------------------------------------------- -// StartStates -- maps characters to start states of tokens -// ----------------------------------------------------------------------------------- -class StartStates { - - private static class Elem { - - public int key, val; - public Elem next; - - public Elem(int key, int val) { - this.key = key; - this.val = val; - } - } - - private Elem[] tab = new Elem[128]; - - public void set(int key, int val) { - Elem e = new Elem(key, val); - int k = key % 128; - e.next = tab[k]; - tab[k] = e; - } - - public int state(int key) { - Elem e = tab[key % 128]; - while (e != null && e.key != key) - e = e.next; - return e == null ? 0 : e.val; - } -} - -// ----------------------------------------------------------------------------------- -// Scanner -// ----------------------------------------------------------------------------------- -@SuppressWarnings({"rawtypes", "unchecked"}) -public class Scanner { - - static final char EOL = '\n'; - static final int eofSym = 0; --->declarations - - public Buffer buffer; // scanner buffer - - Token t; // current token - int ch; // current input character - int pos; // byte position of current character - int charPos; // position by unicode characters starting with 0 - int col; // column number of current character - int line; // line number of current character - int oldEols; // EOLs that appeared in a comment; - static final StartStates start; // maps initial token character to start state - static final Map literals; // maps literal strings to literal kinds - - Token tokens; // list of tokens already peeked (first token is a dummy) - Token pt; // current peek token - - char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged - int tlen; // length of current token - - static { - start = new StartStates(); - literals = new HashMap(); --->initialization - } - - public Scanner(String fileName) { - buffer = new Buffer(fileName); - Init(); - } - - public Scanner(InputStream s) { - buffer = new Buffer(s); - Init(); - } - - void Init() { - pos = -1; - line = 1; - col = 0; - charPos = -1; - oldEols = 0; - NextCh(); - if (ch == 0xEF) { // check optional byte order mark for UTF-8 - NextCh(); - int ch1 = ch; - NextCh(); - int ch2 = ch; - if (ch1 != 0xBB || ch2 != 0xBF) { - throw new FatalError("Illegal byte order mark at start of file"); - } - buffer = new UTF8Buffer(buffer); - col = 0; - charPos = -1; - NextCh(); - } - pt = tokens = new Token(); // first token is a dummy - } - - void NextCh() { - if (oldEols > 0) { - ch = EOL; - oldEols--; - } else { - pos = buffer.getPos(); - // buffer reads unicode chars, if UTF8 has been detected - ch = buffer.Read(); - col++; - charPos++; - // replace isolated '\r' by '\n' in order to make - // eol handling uniform across Windows, Unix and Mac - if (ch == '\r' && buffer.Peek() != '\n') - ch = EOL; - if (ch == EOL) { - line++; - col = 0; - } - } --->casing - } - - void AddCh() { - if (tlen >= tval.length) { - char[] newBuf = new char[2 * tval.length]; - System.arraycopy(tval, 0, newBuf, 0, tval.length); - tval = newBuf; - } - if (ch != Buffer.EOF) { --->casing2 - NextCh(); - } - } - --->comments - - void CheckLiteral() { - String val = t.val; --->casing3 - Object kind = literals.get(val); - if (kind != null) { - t.kind = ((Integer) kind).intValue(); - } - } - - Token NextToken() { - while (ch == ' ' || --->scan1 - ) NextCh(); --->scan2 - int recKind = noSym; - int recEnd = pos; - t = new Token(); - t.pos = pos; - t.col = col; - t.line = line; - t.charPos = charPos; - int state = start.state(ch); - tlen = 0; - AddCh(); - - loop: for (;;) { - switch (state) { - case -1: { - t.kind = eofSym; - break loop; - } // NextCh already done - case 0: { - if (recKind != noSym) { - tlen = recEnd - t.pos; - SetScannerBehindT(); - } - t.kind = recKind; - break loop; - } // NextCh already done --->scan3 - } - } - t.val = new String(tval, 0, tlen); - return t; - } - - private void SetScannerBehindT() { - buffer.setPos(t.pos); - NextCh(); - line = t.line; - col = t.col; - charPos = t.charPos; - for (int i = 0; i < tlen; i++) - NextCh(); - } - - // get the next token (possibly a token already seen during peeking) - public Token Scan() { - if (tokens.next == null) { - return NextToken(); - } else { - pt = tokens = tokens.next; - return tokens; - } - } - - // get the next token, ignore pragmas - public Token Peek() { - do { - if (pt.next == null) { - pt.next = NextToken(); - } - pt = pt.next; - } while (pt.kind > maxT); // skip pragmas - - return pt; - } - - // make sure that peeking starts at current scan position - public void ResetPeek() { - pt = tokens; - } - - // The following methods are used for the CLNG Editor and will be called with java.Reflection. - // If the editor won't be used these 3 functions are obsolete, - // otherwise changes within the signature of the methods will result in Syntax Highlighting not working properly -// anymore. - - // get the offset of the next Token - public int getPeekTokenOffset() { - return pt.pos; - } - - // get the String value of the Token - public String getPeekTokenVal() { - return pt.val; - } - - // get the Kind value of the Token - public int getPeekTokenKind() { - return pt.kind; - } - -} // end Scanner diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,654 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ - -// The content of this file is automatically generated. DO NOT EDIT. - -package com.oracle.truffle.sl.parser; - -import java.io.*; -import java.util.*; - -// Checkstyle: stop -// @formatter:off -class Token { - - public int kind; // token kind - public int pos; // token position in bytes in the source text (starting at 0) - public int charPos; // token position in characters in the source text (starting at 0) - public int col; // token column (starting at 1) - public int line; // token line (starting at 1) - public String val; // token value - public Token next; // ML 2005-03-11 Peek tokens are kept in linked list -} - -// ----------------------------------------------------------------------------------- -// Buffer -// ----------------------------------------------------------------------------------- -class Buffer { - - // This Buffer supports the following cases: - // 1) seekable stream (file) - // a) whole stream in buffer - // b) part of stream in buffer - // 2) non seekable stream (network, console) - - public static final int EOF = Character.MAX_VALUE + 1; - private static final int MIN_BUFFER_LENGTH = 1024; // 1KB - private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB - private byte[] buf; // input buffer - private int bufStart; // position of first byte in buffer relative to input stream - private int bufLen; // length of buffer - private int fileLen; // length of input stream (may change if stream is no file) - private int bufPos; // current position in buffer - private RandomAccessFile file; // input stream (seekable) - private InputStream stream; // growing input stream (e.g.: console, network) - - public Buffer(InputStream s) { - stream = s; - fileLen = bufLen = bufStart = bufPos = 0; - buf = new byte[MIN_BUFFER_LENGTH]; - } - - public Buffer(String fileName) { - try { - file = new RandomAccessFile(fileName, "r"); - fileLen = (int) file.length(); - bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH); - buf = new byte[bufLen]; - bufStart = Integer.MAX_VALUE; // nothing in buffer so far - if (fileLen > 0) - setPos(0); // setup buffer to position 0 (start) - else - bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid - if (bufLen == fileLen) - Close(); - } catch (IOException e) { - throw new FatalError("Could not open file " + fileName); - } - } - - // don't use b after this call anymore - // called in UTF8Buffer constructor - protected Buffer(Buffer b) { - buf = b.buf; - bufStart = b.bufStart; - bufLen = b.bufLen; - fileLen = b.fileLen; - bufPos = b.bufPos; - file = b.file; - stream = b.stream; - // keep finalize from closing the file - b.file = null; - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - Close(); - } - - protected void Close() { - if (file != null) { - try { - file.close(); - file = null; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } - } - - public int Read() { - if (bufPos < bufLen) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (getPos() < fileLen) { - setPos(getPos()); // shift buffer start to pos - return buf[bufPos++] & 0xff; // mask out sign bits - } else if (stream != null && ReadNextStreamChunk() > 0) { - return buf[bufPos++] & 0xff; // mask out sign bits - } else { - return EOF; - } - } - - public int Peek() { - int curPos = getPos(); - int ch = Read(); - setPos(curPos); - return ch; - } - - // beg .. begin, zero-based, inclusive, in byte - // end .. end, zero-based, exclusive, in byte - public String GetString(int beg, int end) { - int len = 0; - char[] buffer = new char[end - beg]; - int oldPos = getPos(); - setPos(beg); - while (getPos() < end) - buffer[len++] = (char) Read(); - setPos(oldPos); - return new String(buffer, 0, len); - } - - public int getPos() { - return bufPos + bufStart; - } - - public void setPos(int value) { - if (value >= fileLen && stream != null) { - // Wanted position is after buffer and the stream - // is not seek-able e.g. network or console, - // thus we have to read the stream manually till - // the wanted position is in sight. - while (value >= fileLen && ReadNextStreamChunk() > 0) { - // nothing to do... - } - } - - if (value < 0 || value > fileLen) { - throw new FatalError("buffer out of bounds access, position: " + value); - } - - if (value >= bufStart && value < bufStart + bufLen) { // already in buffer - bufPos = value - bufStart; - } else if (file != null) { // must be swapped in - try { - file.seek(value); - bufLen = file.read(buf); - bufStart = value; - bufPos = 0; - } catch (IOException e) { - throw new FatalError(e.getMessage()); - } - } else { - // set the position to the end of the file, Pos will return fileLen. - bufPos = fileLen - bufStart; - } - } - - // Read the next chunk of bytes from the stream, increases the buffer - // if needed and updates the fields fileLen and bufLen. - // Returns the number of bytes read. - private int ReadNextStreamChunk() { - int free = buf.length - bufLen; - if (free == 0) { - // in the case of a growing input stream - // we can neither seek in the stream, nor can we - // foresee the maximum length, thus we must adapt - // the buffer size on demand. - byte[] newBuf = new byte[bufLen * 2]; - System.arraycopy(buf, 0, newBuf, 0, bufLen); - buf = newBuf; - free = bufLen; - } - - int read; - try { - read = stream.read(buf, bufLen, free); - } catch (IOException ioex) { - throw new FatalError(ioex.getMessage()); - } - - if (read > 0) { - fileLen = bufLen = (bufLen + read); - return read; - } - // end of stream reached - return 0; - } -} - -// ----------------------------------------------------------------------------------- -// UTF8Buffer -// ----------------------------------------------------------------------------------- -class UTF8Buffer extends Buffer { - - UTF8Buffer(Buffer b) { - super(b); - } - - @Override - public int Read() { - int ch; - do { - ch = super.Read(); - // until we find a utf8 start (0xxxxxxx or 11xxxxxx) - } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF)); - if (ch < 128 || ch == EOF) { - // nothing to do, first 127 chars are the same in ascii and utf8 - // 0xxxxxxx or end of file character - } else if ((ch & 0xF0) == 0xF0) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x07; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = super.Read(); - int c4 = ch & 0x3F; - ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4; - } else if ((ch & 0xE0) == 0xE0) { - // 1110xxxx 10xxxxxx 10xxxxxx - int c1 = ch & 0x0F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = super.Read(); - int c3 = ch & 0x3F; - ch = (((c1 << 6) | c2) << 6) | c3; - } else if ((ch & 0xC0) == 0xC0) { - // 110xxxxx 10xxxxxx - int c1 = ch & 0x1F; - ch = super.Read(); - int c2 = ch & 0x3F; - ch = (c1 << 6) | c2; - } - return ch; - } -} - -// ----------------------------------------------------------------------------------- -// StartStates -- maps characters to start states of tokens -// ----------------------------------------------------------------------------------- -class StartStates { - - private static class Elem { - - public int key, val; - public Elem next; - - public Elem(int key, int val) { - this.key = key; - this.val = val; - } - } - - private Elem[] tab = new Elem[128]; - - public void set(int key, int val) { - Elem e = new Elem(key, val); - int k = key % 128; - e.next = tab[k]; - tab[k] = e; - } - - public int state(int key) { - Elem e = tab[key % 128]; - while (e != null && e.key != key) - e = e.next; - return e == null ? 0 : e.val; - } -} - -// ----------------------------------------------------------------------------------- -// Scanner -// ----------------------------------------------------------------------------------- -@SuppressWarnings({"rawtypes", "unchecked"}) -public class Scanner { - - static final char EOL = '\n'; - static final int eofSym = 0; - static final int maxT = 31; - static final int noSym = 31; - - - public Buffer buffer; // scanner buffer - - Token t; // current token - int ch; // current input character - int pos; // byte position of current character - int charPos; // position by unicode characters starting with 0 - int col; // column number of current character - int line; // line number of current character - int oldEols; // EOLs that appeared in a comment; - static final StartStates start; // maps initial token character to start state - static final Map literals; // maps literal strings to literal kinds - - Token tokens; // list of tokens already peeked (first token is a dummy) - Token pt; // current peek token - - char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged - int tlen; // length of current token - - static { - start = new StartStates(); - literals = new HashMap(); - for (int i = 65; i <= 90; ++i) start.set(i, 1); - for (int i = 97; i <= 122; ++i) start.set(i, 1); - for (int i = 49; i <= 57; ++i) start.set(i, 4); - start.set(34, 2); - start.set(48, 5); - start.set(40, 6); - start.set(44, 7); - start.set(41, 8); - start.set(123, 9); - start.set(125, 10); - start.set(59, 11); - start.set(124, 12); - start.set(38, 14); - start.set(60, 26); - start.set(62, 27); - start.set(61, 28); - start.set(33, 19); - start.set(43, 21); - start.set(45, 22); - start.set(42, 23); - start.set(47, 24); - start.set(46, 25); - start.set(Buffer.EOF, -1); - literals.put("function", new Integer(4)); - literals.put("break", new Integer(10)); - literals.put("continue", new Integer(12)); - literals.put("while", new Integer(13)); - literals.put("if", new Integer(14)); - literals.put("else", new Integer(15)); - literals.put("return", new Integer(16)); - - } - - public Scanner(String fileName) { - buffer = new Buffer(fileName); - Init(); - } - - public Scanner(InputStream s) { - buffer = new Buffer(s); - Init(); - } - - void Init() { - pos = -1; - line = 1; - col = 0; - charPos = -1; - oldEols = 0; - NextCh(); - if (ch == 0xEF) { // check optional byte order mark for UTF-8 - NextCh(); - int ch1 = ch; - NextCh(); - int ch2 = ch; - if (ch1 != 0xBB || ch2 != 0xBF) { - throw new FatalError("Illegal byte order mark at start of file"); - } - buffer = new UTF8Buffer(buffer); - col = 0; - charPos = -1; - NextCh(); - } - pt = tokens = new Token(); // first token is a dummy - } - - void NextCh() { - if (oldEols > 0) { - ch = EOL; - oldEols--; - } else { - pos = buffer.getPos(); - // buffer reads unicode chars, if UTF8 has been detected - ch = buffer.Read(); - col++; - charPos++; - // replace isolated '\r' by '\n' in order to make - // eol handling uniform across Windows, Unix and Mac - if (ch == '\r' && buffer.Peek() != '\n') - ch = EOL; - if (ch == EOL) { - line++; - col = 0; - } - } - - } - - void AddCh() { - if (tlen >= tval.length) { - char[] newBuf = new char[2 * tval.length]; - System.arraycopy(tval, 0, newBuf, 0, tval.length); - tval = newBuf; - } - if (ch != Buffer.EOF) { - tval[tlen++] = (char)ch; - - NextCh(); - } - } - - - boolean Comment0() { - int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos; - NextCh(); - if (ch == '/') { - NextCh(); - for(;;) { - if (ch == 10) { - level--; - if (level == 0) { oldEols = line - line0; NextCh(); return true; } - NextCh(); - } else if (ch == Buffer.EOF) return false; - else NextCh(); - } - } else { - buffer.setPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0; - } - return false; - } - - boolean Comment1() { - int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos; - NextCh(); - if (ch == '*') { - NextCh(); - for(;;) { - if (ch == '*') { - NextCh(); - if (ch == '/') { - level--; - if (level == 0) { oldEols = line - line0; NextCh(); return true; } - NextCh(); - } - } else if (ch == Buffer.EOF) return false; - else NextCh(); - } - } else { - buffer.setPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0; - } - return false; - } - - - void CheckLiteral() { - String val = t.val; - - Object kind = literals.get(val); - if (kind != null) { - t.kind = ((Integer) kind).intValue(); - } - } - - Token NextToken() { - while (ch == ' ' || - ch >= 9 && ch <= 10 || ch == 13 - ) NextCh(); - if (ch == '/' && Comment0() ||ch == '/' && Comment1()) return NextToken(); - int recKind = noSym; - int recEnd = pos; - t = new Token(); - t.pos = pos; - t.col = col; - t.line = line; - t.charPos = charPos; - int state = start.state(ch); - tlen = 0; - AddCh(); - - loop: for (;;) { - switch (state) { - case -1: { - t.kind = eofSym; - break loop; - } // NextCh already done - case 0: { - if (recKind != noSym) { - tlen = recEnd - t.pos; - SetScannerBehindT(); - } - t.kind = recKind; - break loop; - } // NextCh already done - case 1: - recEnd = pos; recKind = 1; - if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;} - else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;} - case 2: - if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;} - else if (ch == '"') {AddCh(); state = 3; break;} - else {state = 0; break;} - case 3: - {t.kind = 2; break loop;} - case 4: - recEnd = pos; recKind = 3; - if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;} - else {t.kind = 3; break loop;} - case 5: - {t.kind = 3; break loop;} - case 6: - {t.kind = 5; break loop;} - case 7: - {t.kind = 6; break loop;} - case 8: - {t.kind = 7; break loop;} - case 9: - {t.kind = 8; break loop;} - case 10: - {t.kind = 9; break loop;} - case 11: - {t.kind = 11; break loop;} - case 12: - if (ch == '|') {AddCh(); state = 13; break;} - else {state = 0; break;} - case 13: - {t.kind = 17; break loop;} - case 14: - if (ch == '&') {AddCh(); state = 15; break;} - else {state = 0; break;} - case 15: - {t.kind = 18; break loop;} - case 16: - {t.kind = 20; break loop;} - case 17: - {t.kind = 22; break loop;} - case 18: - {t.kind = 23; break loop;} - case 19: - if (ch == '=') {AddCh(); state = 20; break;} - else {state = 0; break;} - case 20: - {t.kind = 24; break loop;} - case 21: - {t.kind = 25; break loop;} - case 22: - {t.kind = 26; break loop;} - case 23: - {t.kind = 27; break loop;} - case 24: - {t.kind = 28; break loop;} - case 25: - {t.kind = 30; break loop;} - case 26: - recEnd = pos; recKind = 19; - if (ch == '=') {AddCh(); state = 16; break;} - else {t.kind = 19; break loop;} - case 27: - recEnd = pos; recKind = 21; - if (ch == '=') {AddCh(); state = 17; break;} - else {t.kind = 21; break loop;} - case 28: - recEnd = pos; recKind = 29; - if (ch == '=') {AddCh(); state = 18; break;} - else {t.kind = 29; break loop;} - - } - } - t.val = new String(tval, 0, tlen); - return t; - } - - private void SetScannerBehindT() { - buffer.setPos(t.pos); - NextCh(); - line = t.line; - col = t.col; - charPos = t.charPos; - for (int i = 0; i < tlen; i++) - NextCh(); - } - - // get the next token (possibly a token already seen during peeking) - public Token Scan() { - if (tokens.next == null) { - return NextToken(); - } else { - pt = tokens = tokens.next; - return tokens; - } - } - - // get the next token, ignore pragmas - public Token Peek() { - do { - if (pt.next == null) { - pt.next = NextToken(); - } - pt = pt.next; - } while (pt.kind > maxT); // skip pragmas - - return pt; - } - - // make sure that peeking starts at current scan position - public void ResetPeek() { - pt = tokens; - } - - // The following methods are used for the CLNG Editor and will be called with java.Reflection. - // If the editor won't be used these 3 functions are obsolete, - // otherwise changes within the signature of the methods will result in Syntax Highlighting not working properly -// anymore. - - // get the offset of the next Token - public int getPeekTokenOffset() { - return pt.pos; - } - - // get the String value of the Token - public String getPeekTokenVal() { - return pt.val; - } - - // get the Kind value of the Token - public int getPeekTokenKind() { - return pt.kind; - } - -} // end Scanner diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2012, 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. - */ - -/* - * This is the grammar of SL that is used to automatically generate the Parser.java and Scanner.java - * files. You can download the parser generator Coco/R from http://ssw.jku.at/coco/. Then run - * "java -jar Coco.jar SimpleLanguage.atg" - */ - -COMPILER SimpleLanguage - -CHARACTERS - -letter = 'A'..'Z' + 'a'..'z'. -nonZeroDigit = "123456789". -digit = "0123456789". -cr = '\r'. -lf = '\n'. -tab = '\t'. -stringChar = ANY - "\"" - '\\' - cr - lf. - -TOKENS - -identifier = letter {letter | digit}. -stringLiteral = "\"" { stringChar } "\"". -numericLiteral = "0" | nonZeroDigit { digit }. - -PRAGMAS - -COMMENTS FROM "/*" TO "*/" -COMMENTS FROM "//" TO lf -IGNORE cr + lf + tab - -PRODUCTIONS - - -SimpleLanguage -= -Function -{ - Function -} -. - - -Function -= -"function" -identifier (. Token identifierToken = t; .) -"(" (. int bodyStartPos = t.charPos; .) - (. factory.startFunction(identifierToken, bodyStartPos); .) -[ - identifier (. factory.addFormalParameter(t); .) - { - "," - identifier (. factory.addFormalParameter(t); .) - } -] -")" -Block (. factory.finishFunction(body); .) -. - - - -Block -= (. factory.startBlock(); - List body = new ArrayList<>(); .) -"{" (. int start = t.charPos; .) -{ - Statement (. body.add(s); .) -} -"}" (. int length = (t.charPos + t.val.length()) - start; .) - (. result = factory.finishBlock(body, start, length); .) -. - - -Statement -= (. result = null; .) -( - WhileStatement -| - "break" (. if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } .) - ";" -| - "continue" (. if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } .) - ";" -| - IfStatement -| - ReturnStatement -| - Expression ";" -) -. - - -WhileStatement -= -"while" (. Token whileToken = t; .) -"(" -Expression -")" -Block (. result = factory.createWhile(whileToken, condition, body); .) -. - - -IfStatement -= -"if" (. Token ifToken = t; .) -"(" -Expression -")" -Block (. SLStatementNode elsePart = null; .) -[ - "else" - Block -] (. result = factory.createIf(ifToken, condition, thenPart, elsePart); .) -. - - -ReturnStatement -= -"return" (. Token returnToken = t; - SLExpressionNode value = null; .) -[ - Expression -] (. result = factory.createReturn(returnToken, value); .) -";" -. - - -Expression -= -LogicTerm -{ - "||" (. Token op = t; .) - LogicTerm (. result = factory.createBinary(op, result, right); .) -} -. - - -LogicTerm -= -LogicFactor -{ - "&&" (. Token op = t; .) - LogicFactor (. result = factory.createBinary(op, result, right); .) -} -. - - -LogicFactor -= -Arithmetic -[ - ("<" | "<=" | ">" | ">=" | "==" | "!=" ) (. Token op = t; .) - Arithmetic (. result = factory.createBinary(op, result, right); .) -] -. - - -Arithmetic -= -Term -{ - ("+" | "-") (. Token op = t; .) - Term (. result = factory.createBinary(op, result, right); .) -} -. - - -Term -= -Factor -{ - ("*" | "/") (. Token op = t; .) - Factor (. result = factory.createBinary(op, result, right); .) -} -. - - -Factor -= (. result = null; .) -( - identifier - ( - MemberExpression - | - (. result = factory.createRead(t); .) - ) -| - stringLiteral (. result = factory.createStringLiteral(t); .) -| - numericLiteral (. result = factory.createNumericLiteral(t); .) -| - "(" (. int start = t.charPos; .) - Expression (. SLExpressionNode expr = result; .) - ")" (. int length = (t.charPos + t.val.length()) - start; .) - (. result = factory.createParenExpression(expr, start, length); .) -) -. - - -MemberExpression -= (. result = null; - SLExpressionNode receiver = r; - Token nestedAssignmentName = null; .) -( - "(" (. List parameters = new ArrayList<>(); - SLExpressionNode parameter; - if (receiver == null) { - receiver = factory.createRead(assignmentName); - } .) - [ - Expression (. parameters.add(parameter); .) - { - "," - Expression (. parameters.add(parameter); .) - } - ] - ")" (. Token finalToken = t; .) - (. result = factory.createCall(receiver, parameters, finalToken); .) -| - "=" - Expression (. if (assignmentName == null) { - SemErr("invalid assignment target"); - } else if (assignmentReceiver == null) { - result = factory.createAssignment(assignmentName, value); - } else { - result = factory.createWriteProperty(assignmentReceiver, assignmentName, value); - } .) -| - "." (. if (receiver == null) { - receiver = factory.createRead(assignmentName); - } .) - identifier - (. result = factory.createReadProperty(receiver, t); .) - (. nestedAssignmentName = t; .) -) -[ - MemberExpression -] -. - - -END SimpleLanguage. diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.runtime; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.object.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.sl.builtins.*; -import com.oracle.truffle.sl.nodes.*; -import com.oracle.truffle.sl.nodes.local.*; -import com.oracle.truffle.sl.parser.*; - -/** - * The run-time state of SL during execution. One context is instantiated before any source code is - * parsed, and this context is passed around to all methods that need access to it. For example, the - * context is used during {@link SLNodeFactory parsing} and by {@link SLBuiltinNode#getContext() - * builtin functions}. - *

- * It would be an error to have two different context instances during the execution of one script. - * However, if two separate scripts run in one Java VM at the same time, they have a different - * context. Therefore, the context is not a singleton. - */ -public final class SLContext extends ExecutionContext { - private static final Layout LAYOUT = Layout.createLayout(); - - private final BufferedReader input; - private final PrintWriter output; - private final SLFunctionRegistry functionRegistry; - private final Shape emptyShape; - - public SLContext(BufferedReader input, PrintWriter output) { - this.input = input; - this.output = output; - this.functionRegistry = new SLFunctionRegistry(); - installBuiltins(); - - this.emptyShape = LAYOUT.createShape(new ObjectType()); - } - - /** - * Returns the default input, i.e., the source for the {@link SLReadlnBuiltin}. To allow unit - * testing, we do not use {@link System#in} directly. - */ - public BufferedReader getInput() { - return input; - } - - /** - * The default default, i.e., the output for the {@link SLPrintlnBuiltin}. To allow unit - * testing, we do not use {@link System#out} directly. - */ - public PrintWriter getOutput() { - return output; - } - - /** - * Returns the registry of all functions that are currently defined. - */ - public SLFunctionRegistry getFunctionRegistry() { - return functionRegistry; - } - - /** - * Adds all builtin functions to the {@link SLFunctionRegistry}. This method lists all - * {@link SLBuiltinNode builtin implementation classes}. - */ - private void installBuiltins() { - installBuiltin(SLReadlnBuiltinFactory.getInstance()); - installBuiltin(SLPrintlnBuiltinFactory.getInstance()); - installBuiltin(SLNanoTimeBuiltinFactory.getInstance()); - installBuiltin(SLDefineFunctionBuiltinFactory.getInstance()); - installBuiltin(SLStackTraceBuiltinFactory.getInstance()); - installBuiltin(SLHelloEqualsWorldBuiltinFactory.getInstance()); - installBuiltin(SLAssertTrueBuiltinFactory.getInstance()); - installBuiltin(SLAssertFalseBuiltinFactory.getInstance()); - installBuiltin(SLNewObjectBuiltinFactory.getInstance()); - } - - public void installBuiltin(NodeFactory factory) { - /* - * The builtin node factory is a class that is automatically generated by the Truffle DSL. - * The signature returned by the factory reflects the signature of the @Specialization - * methods in the builtin classes. - */ - int argumentCount = factory.getExecutionSignature().size(); - SLExpressionNode[] argumentNodes = new SLExpressionNode[argumentCount]; - /* - * Builtin functions are like normal functions, i.e., the arguments are passed in as an - * Object[] array encapsulated in SLArguments. A SLReadArgumentNode extracts a parameter - * from this array. - */ - for (int i = 0; i < argumentCount; i++) { - argumentNodes[i] = new SLReadArgumentNode(null, i); - } - /* Instantiate the builtin node. This node performs the actual functionality. */ - SLBuiltinNode builtinBodyNode = factory.createNode(argumentNodes, this); - /* The name of the builtin function is specified via an annotation on the node class. */ - String name = lookupNodeInfo(builtinBodyNode.getClass()).shortName(); - /* Wrap the builtin in a RootNode. Truffle requires all AST to start with a RootNode. */ - SLRootNode rootNode = new SLRootNode(this, new FrameDescriptor(), builtinBodyNode, name); - - /* Register the builtin function in our function registry. */ - getFunctionRegistry().register(name, rootNode); - } - - public static NodeInfo lookupNodeInfo(Class clazz) { - if (clazz == null) { - return null; - } - NodeInfo info = clazz.getAnnotation(NodeInfo.class); - if (info != null) { - return info; - } else { - return lookupNodeInfo(clazz.getSuperclass()); - } - } - - /** - * Evaluate a source, causing any definitions to be registered (but not executed). - * - * @param source The {@link Source} to parse. - */ - public void evalSource(Source source) { - Parser.parseSL(this, source); - } - - public DynamicObject createObject() { - return LAYOUT.newInstance(emptyShape); - } - - public static boolean isSLObject(Object value) { - return LAYOUT.getType().isInstance(value); - } - - public static DynamicObject castSLObject(Object value) { - return LAYOUT.getType().cast(value); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunction.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunction.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +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.sl.runtime; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.interop.*; -import com.oracle.truffle.api.utilities.*; - -/** - * Represents a SL function. On the Truffle level, a callable element is represented by a - * {@link RootCallTarget call target}. This class encapsulates a call target, and adds version - * support: functions in SL can be redefined, i.e. changed at run time. When a function is - * redefined, the call target managed by this function object is changed (and {@link #callTarget} is - * therefore not a final field). - *

- * Function redefinition is expected to be rare, therefore optimized call nodes want to speculate - * that the call target is stable. This is possible with the help of a Truffle {@link Assumption}: a - * call node can keep the call target returned by {@link #getCallTarget()} cached until the - * assumption returned by {@link #getCallTargetStable()} is valid. - *

- * The {@link #callTarget} can be {@code null}. To ensure that only one {@link SLFunction} instance - * per name exists, the {@link SLFunctionRegistry} creates an instance also when performing name - * lookup. A function that has been looked up, i.e., used, but not defined, has no call target. - */ -public final class SLFunction implements TruffleObject { - - /** The name of the function. */ - private final String name; - - /** The current implementation of this function. */ - private RootCallTarget callTarget; - - /** - * Manages the assumption that the {@link #callTarget} is stable. We use the utility class - * {@link CyclicAssumption}, which automatically creates a new {@link Assumption} when the old - * one gets invalidated. - */ - private final CyclicAssumption callTargetStable; - - protected SLFunction(String name) { - this.name = name; - this.callTargetStable = new CyclicAssumption(name); - } - - public String getName() { - return name; - } - - protected void setCallTarget(RootCallTarget callTarget) { - this.callTarget = callTarget; - /* - * We have a new call target. Invalidate all code that speculated that the old call target - * was stable. - */ - callTargetStable.invalidate(); - } - - public RootCallTarget getCallTarget() { - return callTarget; - } - - public Assumption getCallTargetStable() { - return callTargetStable.getAssumption(); - } - - /** - * This method is, e.g., called when using a function literal in a string concatenation. So - * changing it has an effect on SL programs. - */ - @Override - public String toString() { - return name; - } - - /** - * In case you want some of your objects to co-operate with other languages, you need to make - * them implement {@link TruffleObject} and provide additional {@link SLFunctionForeignAccess - * foreign access implementation}. - */ - @Override - public ForeignAccess getForeignAccess() { - return SLFunctionForeignAccess.INSTANCE; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +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.sl.runtime; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.sl.nodes.call.SLDispatchNode; -import com.oracle.truffle.sl.nodes.call.SLDispatchNodeGen; -import java.math.BigInteger; -import java.util.List; - -/** - * Implementation of foreign access for {@link SLFunction}. - */ -final class SLFunctionForeignAccess implements ForeignAccess.Factory { - public static final ForeignAccess INSTANCE = ForeignAccess.create(new SLFunctionForeignAccess()); - - private SLFunctionForeignAccess() { - } - - @Override - public boolean canHandle(TruffleObject o) { - return o instanceof SLFunction; - } - - @Override - public CallTarget accessMessage(Message tree) { - if (Message.createExecute(0).equals(tree)) { - return Truffle.getRuntime().createCallTarget(new SLForeignCallerRootNode()); - } else if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new SLForeignNullCheckNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - - private static class SLForeignCallerRootNode extends RootNode { - @Child private SLDispatchNode dispatch = SLDispatchNodeGen.create(); - - @Override - public Object execute(VirtualFrame frame) { - SLFunction function = (SLFunction) ForeignAccess.getReceiver(frame); - // the calling convention of interop passes the receiver of a - // function call (the this object) - // as an implicit 1st argument; we need to ignore this argument for SL - List args = ForeignAccess.getArguments(frame); - Object[] arr = args.subList(1, args.size()).toArray(); - for (int i = 0; i < arr.length; i++) { - Object a = arr[i]; - if (a instanceof Long) { - continue; - } - if (a instanceof BigInteger) { - continue; - } - if (a instanceof Number) { - arr[i] = ((Number) a).longValue(); - } - } - return dispatch.executeDispatch(frame, function, arr); - } - - } - - private static class SLForeignNullCheckNode extends RootNode { - @Override - public Object execute(VirtualFrame frame) { - Object receiver = ForeignAccess.getReceiver(frame); - return SLNull.SINGLETON == receiver; - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionRegistry.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionRegistry.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.runtime; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.sl.nodes.*; - -/** - * Manages the mapping from function names to {@link SLFunction function objects}. - */ -public final class SLFunctionRegistry { - - private final Map functions = new HashMap<>(); - - /** - * Returns the canonical {@link SLFunction} object for the given name. If it does not exist yet, - * it is created. - */ - public SLFunction lookup(String name) { - SLFunction result = functions.get(name); - if (result == null) { - result = new SLFunction(name); - functions.put(name, result); - } - return result; - } - - /** - * Associates the {@link SLFunction} with the given name with the given implementation root - * node. If the function did not exist before, it defines the function. If the function existed - * before, it redefines the function and the old implementation is discarded. - */ - public void register(String name, SLRootNode rootNode) { - SLFunction function = lookup(name); - RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode); - function.setCallTarget(callTarget); - } - - /** - * Returns the sorted list of all functions, for printing purposes only. - */ - public List getFunctions() { - List result = new ArrayList<>(functions.values()); - Collections.sort(result, new Comparator() { - public int compare(SLFunction f1, SLFunction f2) { - return f1.toString().compareTo(f2.toString()); - } - }); - return result; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLNull.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLNull.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2012, 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.sl.runtime; - -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.TruffleObject; - -/** - * The SL type for a {@code null} (i.e., undefined) value. In Truffle, it is generally discouraged - * to use the Java {@code null} value to represent the guest language {@code null} value. It is not - * possible to specialize on Java {@code null} (since you cannot ask it for the Java class), and - * there is always the danger of a spurious {@link NullPointerException}. Representing the guest - * language {@code null} as a singleton, as in {@link #SINGLETON this class}, is the recommended - * practice. - */ -public final class SLNull implements TruffleObject { - - /** - * The canonical value to represent {@code null} in SL. - */ - public static final SLNull SINGLETON = new SLNull(); - - /** - * Disallow instantiation from outside to ensure that the {@link #SINGLETON} is the only - * instance. - */ - private SLNull() { - } - - /** - * This method is, e.g., called when using the {@code null} value in a string concatenation. So - * changing it has an effect on SL programs. - */ - @Override - public String toString() { - return "null"; - } - - @Override - public ForeignAccess getForeignAccess() { - return SLFunctionForeignAccess.INSTANCE; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/EagerStackTraceDecorator.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/EagerStackTraceDecorator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import org.junit.runner.notification.*; - -class EagerStackTraceDecorator extends TruffleJUnitRunListenerDecorator { - - public EagerStackTraceDecorator(TruffleJUnitRunListener l) { - super(l); - } - - @Override - public void testFailed(Failure failure) { - super.testFailed(failure); - failure.getException().printStackTrace(getWriter()); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/GCAfterTestDecorator.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/GCAfterTestDecorator.java Wed Jun 17 10:01:47 2015 +0200 +++ /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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import org.junit.runner.*; - -final class GCAfterTestDecorator extends TruffleJUnitRunListenerDecorator { - - public GCAfterTestDecorator(TruffleJUnitRunListener l) { - super(l); - } - - @Override - public void testFinished(Description description) { - System.gc(); - super.testFinished(description); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TimingDecorator.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TimingDecorator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import org.junit.runner.*; - -/** - * Timing support for JUnit test runs. - */ -class TimingDecorator extends TruffleJUnitRunListenerDecorator { - - private long startTime; - private long classStartTime; - - public TimingDecorator(TruffleJUnitRunListener l) { - super(l); - } - - @Override - public void testClassStarted(Class clazz) { - classStartTime = System.nanoTime(); - super.testClassStarted(clazz); - } - - @Override - public void testClassFinished(Class clazz) { - long totalTime = System.nanoTime() - classStartTime; - super.testClassFinished(clazz); - getWriter().print(' ' + valueToString(totalTime)); - } - - @Override - public void testStarted(Description description) { - startTime = System.nanoTime(); - super.testStarted(description); - } - - @Override - public void testFinished(Description description) { - long totalTime = System.nanoTime() - startTime; - super.testFinished(description); - getWriter().print(" " + valueToString(totalTime)); - } - - private static String valueToString(long value) { - return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitCore.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitCore.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import java.io.*; -import java.lang.reflect.Modifier; -import java.nio.charset.Charset; -import java.nio.file.*; -import java.util.*; - -import junit.runner.*; - -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.notification.*; -import org.junit.runners.*; -import org.junit.runners.model.*; - -final class TruffleJUnitCore { - - /** - * Run the tests contained in the classes named in the args. A single test method - * can be specified by adding #method after the class name. Only a single test can be run in - * this way. If all tests run successfully, exit with a status of 0. Otherwise exit with a - * status of 1. Write feedback while tests are running and write stack traces for all failed - * tests after the tests all complete. - * - * @param args names of classes in which to find tests to run - */ - public static void main(String... args) { - JUnitSystem system = new RealSystem(); - JUnitCore junitCore = new JUnitCore(); - system.out().println("TruffleJUnitCore"); - system.out().println("JUnit version " + Version.id()); - List> classes = new ArrayList<>(); - String methodName = null; - List missingClasses = new ArrayList<>(); - boolean verbose = false; - boolean enableTiming = false; - boolean failFast = false; - boolean eagerStackTrace = false; - boolean gcAfterTest = false; - - String[] expandedArgs = expandArgs(args); - for (int i = 0; i < expandedArgs.length; i++) { - String each = expandedArgs[i]; - if (each.charAt(0) == '-') { - // command line arguments - if (each.contentEquals("-JUnitVerbose")) { - verbose = true; - } else if (each.contentEquals("-JUnitFailFast")) { - failFast = true; - } else if (each.contentEquals("-JUnitEnableTiming")) { - enableTiming = true; - } else if (each.contentEquals("-JUnitEagerStackTrace")) { - eagerStackTrace = true; - } else if (each.contentEquals("-JUnitGCAfterTest")) { - gcAfterTest = true; - } else { - system.out().println("Unknown command line argument: " + each); - } - - } else { - /* - * Entries of the form class#method are handled specially. Only one can be specified - * on the command line as there's no obvious way to build a runner for multiple - * ones. - */ - if (methodName != null) { - system.out().println("Only a single class and method can be specified: " + each); - System.exit(1); - } else if (each.contains("#")) { - String[] pair = each.split("#"); - if (pair.length != 2) { - system.out().println("Malformed class and method request: " + each); - System.exit(1); - } else if (classes.size() != 0) { - system.out().println("Only a single class and method can be specified: " + each); - System.exit(1); - } else { - methodName = pair[1]; - each = pair[0]; - } - } - try { - Class cls = Class.forName(each, false, TruffleJUnitCore.class.getClassLoader()); - if ((cls.getModifiers() & Modifier.ABSTRACT) == 0) { - classes.add(cls); - } - } catch (ClassNotFoundException e) { - system.out().println("Could not find class: " + each); - Description description = Description.createSuiteDescription(each); - Failure failure = new Failure(description, e); - missingClasses.add(failure); - } - } - } - final TruffleTextListener textListener; - if (!verbose) { - textListener = new TruffleTextListener(system); - } else { - textListener = new TruffleVerboseTextListener(system); - } - TruffleJUnitRunListener listener = textListener; - if (enableTiming) { - listener = new TimingDecorator(listener); - } - if (eagerStackTrace) { - listener = new EagerStackTraceDecorator(listener); - } - if (gcAfterTest) { - listener = new GCAfterTestDecorator(listener); - } - junitCore.addListener(TruffleTextListener.createRunListener(listener)); - Request request; - if (methodName == null) { - request = Request.classes(classes.toArray(new Class[0])); - if (failFast) { - Runner runner = request.getRunner(); - if (runner instanceof ParentRunner) { - ParentRunner parentRunner = (ParentRunner) runner; - parentRunner.setScheduler(new RunnerScheduler() { - public void schedule(Runnable childStatement) { - if (textListener.getLastFailure() == null) { - childStatement.run(); - } - } - - public void finished() { - } - }); - } else { - system.out().println("Unexpected Runner subclass " + runner.getClass().getName() + " - fail fast not supported"); - } - } - } else { - if (failFast) { - system.out().println("Single method selected - fail fast not supported"); - } - request = Request.method(classes.get(0), methodName); - } - Result result = junitCore.run(request); - for (Failure each : missingClasses) { - result.getFailures().add(each); - } - System.exit(result.wasSuccessful() ? 0 : 1); - } - - /** - * Gets the command line for the current process. - * - * @return the command line arguments for the current process or {@code null} if they are not - * available - */ - public static List getProcessCommandLine() { - String processArgsFile = System.getenv().get("MX_SUBPROCESS_COMMAND_FILE"); - if (processArgsFile != null) { - try { - return Files.readAllLines(new File(processArgsFile).toPath(), Charset.forName("UTF-8")); - } catch (IOException e) { - } - } - return null; - } - - /** - * Expand any arguments starting with @ and return the resulting argument array. - * - * @param args - * @return the expanded argument array - */ - private static String[] expandArgs(String[] args) { - List result = null; - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - if (arg.length() > 0 && arg.charAt(0) == '@') { - if (result == null) { - result = new ArrayList<>(); - for (int j = 0; j < i; j++) { - result.add(args[j]); - } - expandArg(arg.substring(1), result); - } - } else if (result != null) { - result.add(arg); - } - } - return result != null ? result.toArray(new String[0]) : args; - } - - /** - * Add each line from {@code filename} to the list {@code args}. - * - * @param filename - * @param args - */ - private static void expandArg(String filename, List args) { - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader(filename)); - - String buf; - while ((buf = br.readLine()) != null) { - args.add(buf); - } - br.close(); - } catch (IOException ioe) { - ioe.printStackTrace(); - System.exit(2); - } finally { - try { - if (br != null) { - br.close(); - } - } catch (IOException ioe) { - ioe.printStackTrace(); - System.exit(3); - } - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitRunListener.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitRunListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import java.io.*; - -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.notification.*; - -interface TruffleJUnitRunListener { - - /** - * Called before any tests have been run. - * - * @param description describes the tests to be run - */ - void testRunStarted(Description description); - - /** - * Called when all tests have finished. - * - * @param result the summary of the test run, including all the tests that failed - */ - void testRunFinished(Result result); - - /** - * Called when a test class is about to be started. - * - * @param clazz the test class - */ - void testClassStarted(Class clazz); - - /** - * Called when all tests of a test class have finished. - * - * @param clazz the test class - */ - void testClassFinished(Class clazz); - - /** - * Called when an atomic test is about to be started. This is also called for ignored tests. - * - * @param description the description of the test that is about to be run (generally a class and - * method name) - */ - void testStarted(Description description); - - /** - * Called when an atomic test has finished, whether the test succeeds, fails or is ignored. - * - * @param description the description of the test that just ran - */ - void testFinished(Description description); - - /** - * Called when an atomic test fails. - * - * @param failure describes the test that failed and the exception that was thrown - */ - void testFailed(Failure failure); - - /** - * Called when a test will not be run, generally because a test method is annotated with - * {@link org.junit.Ignore}. - * - * @param description describes the test that will not be run - */ - void testIgnored(Description description); - - /** - * Called when an atomic test succeeds. - * - * @param description describes the test that will not be run - */ - void testSucceeded(Description description); - - /** - * Called when an atomic test flags that it assumes a condition that is false. - * - * @param failure describes the test that failed and the {@link AssumptionViolatedException} - * that was thrown - */ - void testAssumptionFailure(Failure failure); - - /** - * Called after {@link #testClassFinished(Class)}. - */ - void testClassFinishedDelimiter(); - - /** - * Called after {@link #testClassStarted(Class)}. - */ - void testClassStartedDelimiter(); - - /** - * Called after {@link #testStarted(Description)}. - */ - void testStartedDelimiter(); - - /** - * Called after {@link #testFailed(Failure)}. - */ - void testFinishedDelimiter(); - - PrintStream getWriter(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitRunListenerDecorator.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleJUnitRunListenerDecorator.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import java.io.*; - -import org.junit.runner.*; -import org.junit.runner.notification.*; - -class TruffleJUnitRunListenerDecorator implements TruffleJUnitRunListener { - - private final TruffleJUnitRunListener l; - - public TruffleJUnitRunListenerDecorator(TruffleJUnitRunListener l) { - this.l = l; - } - - @Override - public void testRunStarted(Description description) { - l.testRunStarted(description); - } - - @Override - public void testRunFinished(Result result) { - l.testRunFinished(result); - } - - @Override - public void testAssumptionFailure(Failure failure) { - l.testAssumptionFailure(failure); - } - - @Override - public void testIgnored(Description description) { - l.testIgnored(description); - } - - @Override - public void testClassStarted(Class clazz) { - l.testClassStarted(clazz); - } - - @Override - public void testClassFinished(Class clazz) { - l.testClassFinished(clazz); - } - - @Override - public void testStarted(Description description) { - l.testStarted(description); - } - - @Override - public void testFinished(Description description) { - l.testFinished(description); - } - - @Override - public void testFailed(Failure failure) { - l.testFailed(failure); - } - - @Override - public void testSucceeded(Description description) { - l.testSucceeded(description); - } - - @Override - public PrintStream getWriter() { - return l.getWriter(); - } - - public void testClassFinishedDelimiter() { - l.testClassFinishedDelimiter(); - } - - public void testClassStartedDelimiter() { - l.testClassStartedDelimiter(); - } - - public void testStartedDelimiter() { - l.testStartedDelimiter(); - } - - public void testFinishedDelimiter() { - l.testFinishedDelimiter(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import com.oracle.truffle.api.vm.TruffleVM; -import java.io.IOException; -import java.util.Random; -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * A collection of tests that can certify language implementation to be compliant with most recent - * requirements of the Truffle infrastructure and tooling. Subclass, implement abstract methods and - * include in your test suite. - */ -public abstract class TruffleTCK { - private TruffleVM tckVM; - - protected TruffleTCK() { - } - - /** - * This methods is called before first test is executed. It's purpose is to set a TruffleVM with - * your language up, so it is ready for testing. - * {@link TruffleVM#eval(java.lang.String, java.lang.String) Execute} any scripts you need, and - * prepare global symbols with proper names. The symbols will then be looked up by the - * infrastructure (using the names provided by you from methods like {@link #plusInt()}) and - * used for internal testing. - * - * @return initialized Truffle virtual machine - * @throws java.lang.Exception thrown when the VM preparation fails - */ - protected abstract TruffleVM prepareVM() throws Exception; - - /** - * Mimetype associated with your language. The mimetype will be passed to - * {@link TruffleVM#eval(java.lang.String, java.lang.String)} method of the {@link #prepareVM() - * created TruffleVM}. - * - * @return mime type of the tested language - */ - protected abstract String mimeType(); - - /** - * Name of function which will return value 42 as a number. The return value of the method - * should be instance of {@link Number} and its {@link Number#intValue()} should return - * 42. - * - * @return name of globally exported symbol - */ - protected abstract String fourtyTwo(); - - /** - * Name of a function that returns null. Truffle languages are encouraged to have - * their own type representing null, but when such value is returned from - * {@link TruffleVM#eval}, it needs to be converted to real Java null by sending a - * foreign access isNull message. There is a test to verify it is really true. - * - * @return name of globally exported symbol - */ - protected abstract String returnsNull(); - - /** - * Name of function to add two integer values together. The symbol will be invoked with two - * parameters of type {@link Integer} and expects result of type {@link Number} which's - * {@link Number#intValue()} is equivalent of param1 + param2. - * - * @return name of globally exported symbol - */ - protected abstract String plusInt(); - - /** - * Return a code snippet that is invalid in your language. Its - * {@link TruffleVM#eval(java.lang.String, java.lang.String) evaluation} should fail and yield - * an exception. - * - * @return code snippet invalid in the tested language - */ - protected abstract String invalidCode(); - - private TruffleVM vm() throws Exception { - if (tckVM == null) { - tckVM = prepareVM(); - } - return tckVM; - } - - // - // The tests - // - - @Test - public void testFortyTwo() throws Exception { - TruffleVM.Symbol fourtyTwo = findGlobalSymbol(fourtyTwo()); - - Object res = fourtyTwo.invoke(null); - - assert res instanceof Number : "should yield a number, but was: " + res; - - Number n = (Number) res; - - assert 42 == n.intValue() : "The value is 42 = " + n.intValue(); - } - - @Test - public void testNull() throws Exception { - if (getClass() == TruffleTCK.class) { - return; - } - TruffleVM.Symbol retNull = findGlobalSymbol(returnsNull()); - - Object res = retNull.invoke(null); - - assertNull("Should yield real Java null", res); - } - - @Test - public void testPlusWithInts() throws Exception { - Random r = new Random(); - int a = r.nextInt(100); - int b = r.nextInt(100); - - TruffleVM.Symbol plus = findGlobalSymbol(plusInt()); - - Object res = plus.invoke(null, a, b); - - assert res instanceof Number : "+ on two ints should yield a number, but was: " + res; - - Number n = (Number) res; - - assert a + b == n.intValue() : "The value is correct: (" + a + " + " + b + ") = " + n.intValue(); - } - - @Test(expected = IOException.class) - public void testInvalidTestMethod() throws Exception { - String mime = mimeType(); - String code = invalidCode(); - Object ret = vm().eval(mime, code); - fail("Should yield IOException, but returned " + ret); - } - - private TruffleVM.Symbol findGlobalSymbol(String name) throws Exception { - TruffleVM.Symbol s = vm().findGlobalSymbol(name); - assert s != null : "Symbol " + name + " is not found!"; - return s; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTextListener.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTextListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import java.io.*; - -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.notification.*; - -class TruffleTextListener implements TruffleJUnitRunListener { - - private final PrintStream fWriter; - protected Failure lastFailure; - - public TruffleTextListener(JUnitSystem system) { - this(system.out()); - } - - public TruffleTextListener(PrintStream writer) { - fWriter = writer; - } - - @Override - public PrintStream getWriter() { - return fWriter; - } - - public Failure getLastFailure() { - return lastFailure; - } - - @Override - public void testRunStarted(Description description) { - } - - @Override - public void testRunFinished(Result result) { - } - - @Override - public void testAssumptionFailure(Failure failure) { - } - - @Override - public void testClassStarted(Class clazz) { - } - - @Override - public void testClassFinished(Class clazz) { - } - - @Override - public void testStarted(Description description) { - getWriter().print('.'); - } - - @Override - public void testFinished(Description description) { - } - - @Override - public void testFailed(Failure failure) { - getWriter().print('E'); - lastFailure = failure; - } - - @Override - public void testSucceeded(Description description) { - } - - @Override - public void testIgnored(Description description) { - getWriter().print('I'); - } - - @Override - public void testClassFinishedDelimiter() { - } - - @Override - public void testClassStartedDelimiter() { - } - - @Override - public void testStartedDelimiter() { - } - - @Override - public void testFinishedDelimiter() { - } - - public static RunListener createRunListener(final TruffleJUnitRunListener l) { - return new TextListener(l.getWriter()) { - private Class lastClass; - private boolean failed; - - @Override - public final void testStarted(Description description) { - Class currentClass = description.getTestClass(); - if (currentClass != lastClass) { - if (lastClass != null) { - l.testClassFinished(lastClass); - l.testClassFinishedDelimiter(); - } - lastClass = currentClass; - l.testClassStarted(currentClass); - l.testClassStartedDelimiter(); - } - failed = false; - l.testStarted(description); - l.testStartedDelimiter(); - } - - @Override - public final void testFailure(Failure failure) { - failed = true; - l.testFailed(failure); - } - - @Override - public final void testFinished(Description description) { - // we have to do this because there is no callback for successful tests - if (!failed) { - l.testSucceeded(description); - } - l.testFinished(description); - l.testFinishedDelimiter(); - } - - @Override - public void testIgnored(Description description) { - l.testStarted(description); - l.testStartedDelimiter(); - l.testIgnored(description); - l.testFinished(description); - l.testFinishedDelimiter(); - } - - @Override - public void testRunStarted(Description description) { - l.testRunStarted(description); - } - - @Override - public void testRunFinished(Result result) { - if (lastClass != null) { - l.testClassFinished(lastClass); - } - l.testRunFinished(result); - super.testRunFinished(result); - } - - @Override - public void testAssumptionFailure(Failure failure) { - l.testAssumptionFailure(failure); - } - - }; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleVerboseTextListener.java --- a/graal/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleVerboseTextListener.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tck; - -import java.io.*; - -import org.junit.internal.*; -import org.junit.runner.*; -import org.junit.runner.notification.*; - -class TruffleVerboseTextListener extends TruffleTextListener { - - public TruffleVerboseTextListener(JUnitSystem system) { - this(system.out()); - } - - public TruffleVerboseTextListener(PrintStream writer) { - super(writer); - } - - @Override - public void testClassStarted(Class clazz) { - getWriter().print(clazz.getName() + " started"); - } - - @Override - public void testClassFinished(Class clazz) { - getWriter().print(clazz.getName() + " finished"); - } - - @Override - public void testStarted(Description description) { - getWriter().print(" " + description.getMethodName() + ": "); - } - - @Override - public void testIgnored(Description description) { - getWriter().print("Ignored"); - } - - @Override - public void testSucceeded(Description description) { - getWriter().print("Passed"); - } - - @Override - public void testAssumptionFailure(Failure failure) { - getWriter().printf("(%s) ", failure.getMessage()); - } - - @Override - public void testFailed(Failure failure) { - getWriter().print("FAILED"); - lastFailure = failure; - } - - @Override - public void testClassFinishedDelimiter() { - getWriter().println(); - } - - @Override - public void testClassStartedDelimiter() { - getWriter().println(); - } - - @Override - public void testFinishedDelimiter() { - getWriter().println(); - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/Breakpoint.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/Breakpoint.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -public abstract class Breakpoint { - - /** - * A general model of the states occupied by a breakpoint during its lifetime. - */ - public enum BreakpointState { - - /** - * Not attached, enabled. - *

- * Created for a source location but not yet attached: perhaps just created and the source - * hasn't been loaded yet; perhaps source has been loaded, but the line location isn't - * probed so a breakpoint cannot be attached. Can be either enabled or disabled. - */ - ENABLED_UNRESOLVED("Enabled/Unresolved"), - - /** - * Not attached, disabled. - *

- * Created for a source location but not yet attached: perhaps just created and the source - * hasn't been loaded yet; perhaps source has been loaded, but the line location isn't - * probed so a breakpoint cannot be attached. - */ - DISABLED_UNRESOLVED("Disabled/Unresolved"), - - /** - * Attached, instrument enabled. - *

- * Is currently implemented by some {@link Instrument}, which is attached to a {@link Probe} - * at a specific node in the AST, and the breakpoint is enabled. - */ - ENABLED("Enabled"), - - /** - * Attached, instrument disabled. - *

- * Is currently implemented by some {@link Instrument}, which is attached to a {@link Probe} - * at a specific node in the AST, and the breakpoint is disabled. - */ - DISABLED("Disabled"), - - /** - * Not attached, instrument is permanently disabled. - */ - DISPOSED("Disposed"); - - private final String name; - - BreakpointState(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - - } - - private static int nextBreakpointId = 0; - - private final int id; - private final int groupId; - private final boolean isOneShot; - - private int ignoreCount; - - private int hitCount = 0; - - private BreakpointState state; - - Breakpoint(BreakpointState state, int groupId, int ignoreCount, boolean isOneShot) { - this.state = state; - this.id = nextBreakpointId++; - this.groupId = groupId; - this.isOneShot = isOneShot; - this.ignoreCount = ignoreCount; - } - - /** - * Unique ID. - */ - public final int getId() { - return id; - } - - /** - * Group ID, set when created. - */ - public final int getGroupId() { - return groupId; - } - - /** - * Enables or disables this breakpoint's AST instrumentation. The breakpoint is enabled by - * default. - * - * @param enabled true to activate the instrumentation, false to - * deactivate the instrumentation so that it has no effect. - */ - public abstract void setEnabled(boolean enabled); - - /** - * Is this breakpoint active? - */ - public abstract boolean isEnabled(); - - /** - * Sets the condition on this breakpoint, {@code null} to make it unconditional. - * - * @param expr if non{@code -null}, a boolean expression, expressed in the guest language, to be - * evaluated in the lexical context at the breakpoint location. - * @throws DebugException if condition is invalid - * @throws UnsupportedOperationException if the breakpoint does not support conditions - */ - public abstract void setCondition(String expr) throws DebugException; - - /** - * Gets the string, expressed in the Guest Language, that defines the current condition on this - * breakpoint; {@code null} if this breakpoint is currently unconditional. - */ - public String getCondition() { - return null; - } - - /** - * Does this breakpoint remove itself after first activation? - */ - public final boolean isOneShot() { - return isOneShot; - } - - /** - * Gets the number of hits left to be ignored before halting. - */ - public final int getIgnoreCount() { - return ignoreCount; - } - - /** - * Change the threshold for when this breakpoint should start causing a break. When both an - * ignore count and a {@linkplain #setCondition(String) condition} are specified, the condition - * is evaluated first: if {@code false} it is not considered to be a hit. In other words, the - * ignore count is for successful conditions only. - */ - public final void setIgnoreCount(int ignoreCount) { - this.ignoreCount = ignoreCount; - } - - /** - * Number of times this breakpoint has reached, with one exception; if the breakpoint has a - * condition that evaluates to {@code false}, it does not count as a hit. - */ - public final int getHitCount() { - return hitCount; - } - - /** - * Disables this breakpoint and removes any associated instrumentation; it becomes permanently - * inert. - */ - public abstract void dispose(); - - /** - * Gets a human-sensible description of this breakpoint's location in a {@link Source}. - */ - public abstract String getLocationDescription(); - - public final BreakpointState getState() { - return state; - } - - final void assertState(BreakpointState s) { - assert state == s; - } - - final void setState(BreakpointState state) { - this.state = state; - } - - /** - * Assumes that all conditions for causing the break have been satisfied, so increments the - * hit count. Then checks if the ignore count has been exceeded, and if so - * returns {@code true}. If not, it still counts as a hit but should be ignored. - * - * @return whether to proceed - */ - final boolean incrHitCountCheckIgnore() { - return ++hitCount > ignoreCount; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(getClass().getSimpleName()); - sb.append(" state="); - sb.append(getState() == null ? "" : getState().getName()); - if (isOneShot()) { - sb.append(", " + "One-Shot"); - } - if (getCondition() != null) { - sb.append(", condition=\"" + getCondition() + "\""); - } - return sb.toString(); - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugClient.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugClient.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import java.util.*; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.vm.TruffleVM.Language; - -/** - * A client of the debugger where certain events should be posted. - * - * @see DebugEngine - */ -public interface DebugClient { - - /** - * Notifies client that program execution has been halted at some location; execution will - * resume when this method returns. - * - * @param astNode AST node that is just about to be executed - * @param mFrame frame that will be passed to the node when executed - * @param warnings any warnings generated since the most recent halt. - */ - void haltedAt(Node astNode, MaterializedFrame mFrame, List warnings); - - /** - * Gets information and services for the language being debugged. - */ - Language getLanguage(); -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugEngine.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugEngine.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,851 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.vm.TruffleVM.Language; -import com.oracle.truffle.tools.debug.engine.DebugExecutionSupport.DebugExecutionListener; - -/** - * Language-agnostic engine for running Truffle languages under debugging control. - */ -public final class DebugEngine { - - private static final boolean TRACE = false; - private static final String TRACE_PREFIX = "DEBUG ENGINE: "; - - private static final PrintStream OUT = System.out; - - private static final SyntaxTag STEPPING_TAG = StandardSyntaxTag.STATEMENT; - private static final SyntaxTag CALL_TAG = StandardSyntaxTag.CALL; - - private static void trace(String format, Object... args) { - if (TRACE) { - OUT.println(TRACE_PREFIX + String.format(format, args)); - } - } - - interface BreakpointCallback { - - /** - * Passes control to the debugger with execution suspended. - */ - void haltedAt(Node astNode, MaterializedFrame mFrame, String haltReason); - } - - interface WarningLog { - - /** - * Logs a warning that is kept until the start of the next execution. - */ - void addWarning(String warning); - } - - private final Language language; - - /** - * The client of this engine. - */ - private final DebugClient debugClient; - - private final DebugExecutionSupport executionSupport; - - /** - * Implementation of line-oriented breakpoints. - */ - private final LineBreakpointFactory lineBreaks; - - /** - * Implementation of tag-oriented breakpoints. - */ - private final TagBreakpointFactory tagBreaks; - - /** - * Head of the stack of executions. - */ - private DebugExecutionContext debugContext; - - /** - * @param debugClient - * @param language - */ - private DebugEngine(DebugClient debugClient, Language language) { - this.debugClient = debugClient; - this.language = language; - this.executionSupport = new DebugExecutionSupport(language.getShortName(), language.getDebugSupport()); - - Source.setFileCaching(true); - - // Initialize execution context stack - debugContext = new DebugExecutionContext(null, null); - prepareContinue(); - debugContext.contextTrace("START EXEC DEFAULT"); - - executionSupport.addExecutionListener(new DebugExecutionListener() { - - public void executionStarted(Source source, boolean stepInto) { - // Push a new execution context onto stack - DebugEngine.this.debugContext = new DebugExecutionContext(source, DebugEngine.this.debugContext); - if (stepInto) { - DebugEngine.this.prepareStepInto(1); - } else { - DebugEngine.this.prepareContinue(); - } - DebugEngine.this.debugContext.contextTrace("START EXEC "); - } - - public void executionEnded() { - DebugEngine.this.lineBreaks.disposeOneShots(); - DebugEngine.this.tagBreaks.disposeOneShots(); - DebugEngine.this.debugContext.clearStrategy(); - DebugEngine.this.debugContext.contextTrace("END EXEC "); - // Pop the stack of execution contexts. - DebugEngine.this.debugContext = DebugEngine.this.debugContext.predecessor; - } - }); - - final BreakpointCallback breakpointCallback = new BreakpointCallback() { - - @TruffleBoundary - public void haltedAt(Node astNode, MaterializedFrame mFrame, String haltReason) { - debugContext.halt(astNode, mFrame, true, haltReason); - } - }; - - final WarningLog warningLog = new WarningLog() { - - public void addWarning(String warning) { - assert debugContext != null; - debugContext.logWarning(warning); - } - }; - - this.lineBreaks = new LineBreakpointFactory(executionSupport, breakpointCallback, warningLog); - - this.tagBreaks = new TagBreakpointFactory(executionSupport, breakpointCallback, warningLog); - } - - public static DebugEngine create(DebugClient debugClient, Language language) { - return new DebugEngine(debugClient, language); - } - - /** - * Runs a script. If "StepInto" is requested, halts at the first location tagged as a - * {@linkplain StandardSyntaxTag#STATEMENT STATEMENT}. - * - * @throws DebugException if an unexpected failure occurs - */ - public void run(Source source, boolean stepInto) throws DebugException { - executionSupport.run(source, stepInto); - } - - /** - * Sets a breakpoint to halt at a source line. - * - * @param groupId - * @param ignoreCount number of hits to ignore before halting - * @param lineLocation where to set the breakpoint (source, line number) - * @param oneShot breakpoint disposes itself after fist hit, if {@code true} - * @return a new breakpoint, initially enabled - * @throws DebugException if the breakpoint can not be set. - */ - @TruffleBoundary - public LineBreakpoint setLineBreakpoint(int groupId, int ignoreCount, LineLocation lineLocation, boolean oneShot) throws DebugException { - return lineBreaks.create(groupId, ignoreCount, lineLocation, oneShot); - } - - /** - * Sets a breakpoint to halt at any node holding a specified {@link SyntaxTag}. - * - * @param groupId - * @param ignoreCount number of hits to ignore before halting - * @param oneShot if {@code true} breakpoint removes it self after a hit - * @return a new breakpoint, initially enabled - * @throws DebugException if the breakpoint already set - */ - @TruffleBoundary - public Breakpoint setTagBreakpoint(int groupId, int ignoreCount, SyntaxTag tag, boolean oneShot) throws DebugException { - return tagBreaks.create(groupId, ignoreCount, tag, oneShot); - } - - /** - * Finds a breakpoint created by this engine, but not yet disposed, by id. - */ - @TruffleBoundary - public Breakpoint findBreakpoint(long id) { - final Breakpoint breakpoint = lineBreaks.find(id); - return breakpoint == null ? tagBreaks.find(id) : breakpoint; - } - - /** - * Gets all existing breakpoints, whatever their status, in natural sorted order. Modification - * save. - */ - @TruffleBoundary - public Collection getBreakpoints() { - final Collection result = new ArrayList<>(); - result.addAll(lineBreaks.getAll()); - result.addAll(tagBreaks.getAll()); - return result; - } - - /** - * Prepare to execute in Continue mode when guest language program execution resumes. In this - * mode: - *

    - *
  • Execution will continue until either: - *
      - *
    1. execution arrives at a node to which an enabled breakpoint is attached, - * or:
    2. - *
    3. execution completes.
    4. - *
    - *
- */ - @TruffleBoundary - public void prepareContinue() { - debugContext.setStrategy(new Continue()); - } - - /** - * Prepare to execute in StepInto mode when guest language program execution resumes. In this - * mode: - *
    - *
  • User breakpoints are disabled.
  • - *
  • Execution will continue until either: - *
      - *
    1. execution arrives at a node with the tag {@linkplain StandardSyntaxTag#STATEMENT - * STATMENT}, or:
    2. - *
    3. execution completes.
    4. - *
    - *
  • - * StepInto mode persists only through one resumption (i.e. {@code stepIntoCount} steps), and - * reverts by default to Continue mode.
  • - *
- * - * @param stepCount the number of times to perform StepInto before halting - * @throws IllegalArgumentException if the specified number is {@code <= 0} - */ - @TruffleBoundary - public void prepareStepInto(int stepCount) { - if (stepCount <= 0) { - throw new IllegalArgumentException(); - } - debugContext.setStrategy(new StepInto(stepCount)); - } - - /** - * Prepare to execute in StepOut mode when guest language program execution resumes. In this - * mode: - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution will continue until either: - *
      - *
    1. execution arrives at the nearest enclosing call site on the stack, or
    2. - *
    3. execution completes.
    4. - *
    - *
  • StepOut mode persists only through one resumption, and reverts by default to Continue - * mode.
  • - *
- */ - @TruffleBoundary - public void prepareStepOut() { - debugContext.setStrategy(new StepOut()); - } - - /** - * Prepare to execute in StepOver mode when guest language program execution resumes. In this - * mode: - *
    - *
  • Execution will continue until either: - *
      - *
    1. execution arrives at a node with the tag {@linkplain StandardSyntaxTag#STATEMENT - * STATEMENT} when not nested in one or more function/method calls, or:
    2. - *
    3. execution arrives at a node to which a breakpoint is attached and when nested in one or - * more function/method calls, or:
    4. - *
    5. execution completes.
    6. - *
    - *
  • StepOver mode persists only through one resumption (i.e. {@code stepOverCount} steps), - * and reverts by default to Continue mode.
  • - *
- * - * @param stepCount the number of times to perform StepInto before halting - * @throws IllegalArgumentException if the specified number is {@code <= 0} - */ - @TruffleBoundary - public void prepareStepOver(int stepCount) { - if (stepCount <= 0) { - throw new IllegalArgumentException(); - } - debugContext.setStrategy(new StepOver(stepCount)); - } - - /** - * Gets the stack frames from the (topmost) halted Truffle execution; {@code null} null if no - * execution. - */ - @TruffleBoundary - public List getStack() { - return debugContext == null ? null : debugContext.getFrames(); - } - - /** - * Evaluates code in a halted execution context, at top-level if mFrame==null. - * - * @throws DebugException - */ - public Object eval(Source source, Node node, MaterializedFrame mFrame) throws DebugException { - return executionSupport.evalInContext(source, node, mFrame); - } - - /** - * A mode of user navigation from a current code location to another, e.g "step in" vs. - * "step over". - */ - private abstract class StepStrategy { - - private DebugExecutionContext context; - protected final String strategyName; - - protected StepStrategy() { - this.strategyName = getClass().getSimpleName(); - } - - final String getName() { - return strategyName; - } - - /** - * Reconfigure the debugger so that when execution continues the program will halt at the - * location specified by this strategy. - */ - final void enable(DebugExecutionContext c, int stackDepth) { - this.context = c; - setStrategy(stackDepth); - } - - /** - * Return the debugger to the default navigation mode. - */ - final void disable() { - unsetStrategy(); - } - - @TruffleBoundary - final void halt(Node astNode, MaterializedFrame mFrame, boolean before) { - context.halt(astNode, mFrame, before, this.getClass().getSimpleName()); - } - - @TruffleBoundary - final void replaceStrategy(StepStrategy newStrategy) { - context.setStrategy(newStrategy); - } - - @TruffleBoundary - protected final void strategyTrace(String action, String format, Object... args) { - if (TRACE) { - context.contextTrace("%s (%s) %s", action, strategyName, String.format(format, args)); - } - } - - @TruffleBoundary - protected final void suspendUserBreakpoints() { - lineBreaks.setActive(false); - tagBreaks.setActive(false); - } - - @SuppressWarnings("unused") - protected final void restoreUserBreakpoints() { - lineBreaks.setActive(true); - tagBreaks.setActive(true); - } - - /** - * Reconfigure the debugger so that when execution continues, it will do so using this mode - * of navigation. - */ - protected abstract void setStrategy(int stackDepth); - - /** - * Return to the debugger to the default mode of navigation. - */ - protected abstract void unsetStrategy(); - } - - /** - * Strategy: the null stepping strategy. - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution continues until either: - *
      - *
    1. execution arrives at a node with attached user breakpoint, or:
    2. - *
    3. execution completes.
    4. - *
    - *
- */ - private final class Continue extends StepStrategy { - - @Override - protected void setStrategy(int stackDepth) { - } - - @Override - protected void unsetStrategy() { - } - } - - /** - * Strategy: per-statement stepping. - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution continues until either: - *
      - *
    1. execution arrives at a STATEMENT node, or:
    2. - *
    3. execution returns to a CALL node and the call stack is smaller then when - * execution started, or:
    4. - *
    5. execution completes.
    6. - *
    - *
- * - * @see DebugEngine#prepareStepInto(int) - */ - private final class StepInto extends StepStrategy { - private int unfinishedStepCount; - - StepInto(int stepCount) { - super(); - this.unfinishedStepCount = stepCount; - } - - @Override - protected void setStrategy(final int stackDepth) { - Probe.setBeforeTagTrap(new SyntaxTagTrap(STEPPING_TAG) { - - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - // HALT: just before statement - --unfinishedStepCount; - strategyTrace("TRAP BEFORE", "unfinished steps=%d", unfinishedStepCount); - // Should run in fast path - if (unfinishedStepCount <= 0) { - halt(node, mFrame, true); - } - strategyTrace("RESUME BEFORE", ""); - } - }); - Probe.setAfterTagTrap(new SyntaxTagTrap(CALL_TAG) { - - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - --unfinishedStepCount; - strategyTrace(null, "TRAP AFTER unfinished steps=%d", unfinishedStepCount); - if (currentStackDepth() < stackDepth) { - // HALT: just "stepped out" - if (unfinishedStepCount <= 0) { - halt(node, mFrame, false); - } - } - strategyTrace("RESUME AFTER", ""); - } - }); - } - - @Override - protected void unsetStrategy() { - Probe.setBeforeTagTrap(null); - Probe.setAfterTagTrap(null); - } - } - - /** - * Strategy: execution to nearest enclosing call site. - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution continues until either: - *
      - *
    1. execution arrives at a node with attached user breakpoint, or:
    2. - *
    3. execution returns to a CALL node and the call stack is smaller than when - * execution started, or:
    4. - *
    5. execution completes.
    6. - *
    - *
- * - * @see DebugEngine#prepareStepOut() - */ - private final class StepOut extends StepStrategy { - - @Override - protected void setStrategy(final int stackDepth) { - Probe.setAfterTagTrap(new SyntaxTagTrap(CALL_TAG) { - - @TruffleBoundary - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - // HALT: - final int currentStackDepth = currentStackDepth(); - strategyTrace("TRAP AFTER", "stackDepth: start=%d current=%d", stackDepth, currentStackDepth); - if (currentStackDepth < stackDepth) { - halt(node, mFrame, false); - } - strategyTrace("RESUME AFTER", ""); - } - }); - } - - @Override - protected void unsetStrategy() { - Probe.setAfterTagTrap(null); - } - } - - /** - * Strategy: per-statement stepping, so long as not nested in method calls (i.e. at original - * stack depth). - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution continues until either: - *
      - *
    1. execution arrives at a STATEMENT node with stack depth no more than when started - * or:
    2. - *
    3. the program completes.
    4. - *
    - *
- */ - private final class StepOver extends StepStrategy { - private int unfinishedStepCount; - - StepOver(int stepCount) { - this.unfinishedStepCount = stepCount; - } - - @Override - protected void setStrategy(int stackDepth) { - Probe.setBeforeTagTrap(new SyntaxTagTrap(STEPPING_TAG) { - - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - final int currentStackDepth = currentStackDepth(); - if (currentStackDepth <= stackDepth) { - // HALT: stack depth unchanged or smaller; treat like StepInto - --unfinishedStepCount; - if (TRACE) { - strategyTrace("TRAP BEFORE", "unfinished steps=%d stackDepth start=%d current=%d", unfinishedStepCount, stackDepth, currentStackDepth); - } - // Test should run in fast path - if (unfinishedStepCount <= 0) { - halt(node, mFrame, true); - } - } else { - // CONTINUE: Stack depth increased; don't count as a step - strategyTrace("STEP INTO", "unfinished steps=%d stackDepth start=%d current=%d", unfinishedStepCount, stackDepth, currentStackDepth); - // Stop treating like StepInto, start treating like StepOut - replaceStrategy(new StepOverNested(unfinishedStepCount, stackDepth)); - } - strategyTrace("RESUME BEFORE", ""); - } - }); - - Probe.setAfterTagTrap(new SyntaxTagTrap(CALL_TAG) { - - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - final int currentStackDepth = currentStackDepth(); - if (currentStackDepth < stackDepth) { - // HALT: just "stepped out" - --unfinishedStepCount; - strategyTrace("TRAP AFTER", "unfinished steps=%d stackDepth: start=%d current=%d", unfinishedStepCount, stackDepth, currentStackDepth); - // Should run in fast path - if (unfinishedStepCount <= 0) { - halt(node, mFrame, false); - } - strategyTrace("RESUME AFTER", ""); - } - } - }); - } - - @Override - protected void unsetStrategy() { - Probe.setBeforeTagTrap(null); - Probe.setAfterTagTrap(null); - } - } - - /** - * Strategy: per-statement stepping, not into method calls, in effect while at increased stack - * depth - *
    - *
  • User breakpoints are enabled.
  • - *
  • Execution continues until either: - *
      - *
    1. execution arrives at a STATEMENT node with stack depth no more than when started - * or:
    2. - *
    3. the program completes or:
    4. - *
    - *
- */ - private final class StepOverNested extends StepStrategy { - private int unfinishedStepCount; - private final int startStackDepth; - - StepOverNested(int stepCount, int startStackDepth) { - this.unfinishedStepCount = stepCount; - this.startStackDepth = startStackDepth; - } - - @Override - protected void setStrategy(int stackDepth) { - Probe.setBeforeTagTrap(new SyntaxTagTrap(STEPPING_TAG) { - - @Override - public void tagTrappedAt(Node node, MaterializedFrame mFrame) { - final int currentStackDepth = currentStackDepth(); - if (currentStackDepth <= startStackDepth) { - // At original step depth (or smaller) after being nested - --unfinishedStepCount; - strategyTrace("TRAP AFTER", "unfinished steps=%d stackDepth start=%d current=%d", unfinishedStepCount, stackDepth, currentStackDepth); - if (unfinishedStepCount <= 0) { - halt(node, mFrame, false); - } - // TODO (mlvdv) fixme for multiple steps - strategyTrace("RESUME BEFORE", ""); - } - } - }); - } - - @Override - protected void unsetStrategy() { - Probe.setBeforeTagTrap(null); - } - } - - /** - * Information and debugging state for a single Truffle execution (which make take place over - * one or more suspended executions). This holds interaction state, for example what is - * executing (e.g. some {@link Source}), what the execution mode is ("stepping" or - * "continuing"). When not running, this holds a cache of the Truffle stack for this particular - * execution, effectively hiding the Truffle stack for any currently suspended executions (down - * the stack). - */ - private final class DebugExecutionContext { - - // Previous halted context in stack - private final DebugExecutionContext predecessor; - - // The current execution level; first is 0. - private final int level; // Number of contexts suspended below - private final Source source; - private final int contextStackBase; // Where the stack for this execution starts - private final List warnings = new ArrayList<>(); - - private boolean running; - - /** - * The stepping strategy currently configured in the debugger. - */ - private StepStrategy strategy; - - /** - * Where halted; null if running. - */ - private Node haltedNode; - - /** - * Where halted; null if running. - */ - private MaterializedFrame haltedFrame; - - /** - * Cached list of stack frames when halted; null if running. - */ - private List frames = new ArrayList<>(); - - private DebugExecutionContext(Source executionSource, DebugExecutionContext previousContext) { - this.source = executionSource; - this.predecessor = previousContext; - this.level = previousContext == null ? 0 : previousContext.level + 1; - - // "Base" is the number of stack frames for all nested (halted) executions. - this.contextStackBase = currentStackDepth(); - this.running = true; - contextTrace("NEW CONTEXT"); - } - - /** - * Sets up a strategy for the next resumption of execution. - * - * @param stepStrategy - */ - void setStrategy(StepStrategy stepStrategy) { - if (this.strategy == null) { - this.strategy = stepStrategy; - this.strategy.enable(this, currentStackDepth()); - if (TRACE) { - contextTrace("SET MODE -->" + stepStrategy.getName()); - } - } else { - strategy.disable(); - strategy = stepStrategy; - strategy.enable(this, currentStackDepth()); - contextTrace("SWITCH MODE %s-->%s", strategy.getName(), stepStrategy.getName()); - } - } - - void clearStrategy() { - if (strategy != null) { - final StepStrategy oldStrategy = strategy; - strategy.disable(); - strategy = null; - contextTrace("CLEAR MODE %s-->", oldStrategy.getName()); - } - } - - /** - * Handle a program halt, caused by a breakpoint, stepping strategy, or other cause. - * - * @param astNode the guest language node at which execution is halted - * @param mFrame the current execution frame where execution is halted - * @param before {@code true} if halted before the node, else after. - */ - @TruffleBoundary - void halt(Node astNode, MaterializedFrame mFrame, boolean before, String haltReason) { - assert running; - assert frames.isEmpty(); - assert haltedNode == null; - assert haltedFrame == null; - - haltedNode = astNode; - haltedFrame = mFrame; - running = false; - - clearStrategy(); - - // Clean up, just in cased the one-shot breakpoints got confused - lineBreaks.disposeOneShots(); - - // Map the Truffle stack for this execution, ignore nested executions - // The top (current) frame is not produced by the iterator. - frames.add(new FrameDebugDescription(0, haltedNode, Truffle.getRuntime().getCurrentFrame())); - final int contextStackDepth = currentStackDepth() - contextStackBase; - final int[] frameCount = {1}; - Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { - @Override - public FrameInstance visitFrame(FrameInstance frameInstance) { - if (frameCount[0] < contextStackDepth) { - frames.add(new FrameDebugDescription(frameCount[0], frameInstance.getCallNode(), frameInstance)); - frameCount[0] = frameCount[0] + 1; - return null; - } - return frameInstance; - } - }); - - if (TRACE) { - final String reason = haltReason == null ? "" : haltReason + ""; - final String where = before ? "BEFORE" : "AFTER"; - contextTrace("HALT %s : (%s) stack base=%d", where, reason, contextStackBase); - contextTrace("CURRENT STACK:"); - printStack(OUT); - } - - final List recentWarnings = new ArrayList<>(warnings); - warnings.clear(); - - try { - // Pass control to the debug client with current execution suspended - debugClient.haltedAt(astNode, mFrame, recentWarnings); - // Debug client finished normally, execution resumes - // Presume that the client has set a new strategy (or default to Continue) - running = true; - } catch (KillException e) { - contextTrace("KILL"); - throw e; - } finally { - haltedNode = null; - haltedFrame = null; - frames.clear(); - } - - } - - List getFrames() { - return Collections.unmodifiableList(frames); - } - - void logWarning(String warning) { - warnings.add(warning); - } - - // For tracing - private void printStack(PrintStream stream) { - getFrames(); - if (frames == null) { - stream.println(""); - } else { - final Visualizer visualizer = language.getDebugSupport().getVisualizer(); - for (FrameDebugDescription frameDesc : frames) { - final StringBuilder sb = new StringBuilder(" frame " + Integer.toString(frameDesc.index())); - sb.append(":at " + visualizer.displaySourceLocation(frameDesc.node())); - sb.append(":in '" + visualizer.displayMethodName(frameDesc.node()) + "'"); - stream.println(sb.toString()); - } - } - } - - void contextTrace(String format, Object... args) { - if (TRACE) { - final String srcName = (source != null) ? source.getName() : "no source"; - DebugEngine.trace("<%d> %s (%s)", level, String.format(format, args), srcName); - } - } - } - - // TODO (mlvdv) wish there were fast-path access to stack depth - /** - * Depth of current Truffle stack, including nested executions. Includes the top/current frame, - * which the standard iterator does not count: {@code 0} if no executions. - */ - @TruffleBoundary - private static int currentStackDepth() { - final int[] count = {0}; - Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { - @Override - public Void visitFrame(FrameInstance frameInstance) { - count[0] = count[0] + 1; - return null; - } - }); - return count[0] == 0 ? 0 : count[0] + 1; - - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugException.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -/** - * An unexpected failure in the operation of the {@link DebugEngine}. - */ -public class DebugException extends Exception { - - public DebugException(String string) { - super(string); - } - - public DebugException(Exception ex) { - super(ex); - } - - private static final long serialVersionUID = 3307454453821997224L; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugExecutionSupport.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugExecutionSupport.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import java.util.*; - -import com.oracle.truffle.api.debug.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; - -/** - * Access to language-specific support for debugging. - */ -final class DebugExecutionSupport { - - interface DebugExecutionListener { - - /** - * Notifies that execution is about to start and requests initial execution mode. - */ - void executionStarted(Source source, boolean stepInto); - - /** - * Notification that the current execution has just ended. - */ - void executionEnded(); - } - - private final String languageName; - private final DebugSupportProvider provider; - private final List listeners = new ArrayList<>(); - - DebugExecutionSupport(String languageName, DebugSupportProvider provider) { - this.languageName = languageName; - this.provider = provider; - } - - void addExecutionListener(DebugExecutionListener listener) { - assert listener != null; - listeners.add(listener); - } - - String getLanguageName() { - return languageName; - } - - Visualizer getVisualizer() { - return provider.getVisualizer(); - } - - /** - * Runs a script. If "StepInto" is specified, halts at the first location tagged as a - * {@linkplain StandardSyntaxTag#STATEMENT STATEMENT}. - */ - void run(Source source, boolean stepInto) throws DebugException { - for (DebugExecutionListener listener : listeners) { - listener.executionStarted(source, stepInto); - } - try { - provider.run(source); - } catch (DebugSupportException ex) { - throw new DebugException(ex); - } finally { - for (DebugExecutionListener listener : listeners) { - listener.executionEnded(); - } - } - } - - /** - * Evaluates string of language code in a halted execution context, at top level if - * mFrame==null. - * - * @throws DebugException - */ - Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugException { - for (DebugExecutionListener listener : listeners) { - listener.executionStarted(source, false); - } - try { - return provider.evalInContext(source, node, mFrame); - } catch (DebugSupportException ex) { - throw new DebugException(ex); - } finally { - for (DebugExecutionListener listener : listeners) { - listener.executionEnded(); - } - } - } - - /** - * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot} - * that, when executed, computes the result of a textual expression in the language; used to - * create an - * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @param expr a guest language expression - * @param resultListener optional listener for the result of each evaluation. - * @return a new factory - * @throws DebugException if the factory cannot be created, for example if the expression is - * badly formed. - */ - AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugException { - try { - return provider.createAdvancedInstrumentRootFactory(expr, resultListener); - } catch (DebugSupportException ex) { - throw new DebugException(ex); - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/FrameDebugDescription.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/FrameDebugDescription.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A summary description of a Truffle {@link Frame} in a particular stack context. - * - * @see DebugEngine - */ -public final class FrameDebugDescription { - - private final int index; - private final Node node; - private final FrameInstance frameInstance; - - FrameDebugDescription(int index, Node node, FrameInstance frameInstance) { - this.index = index; - this.node = node; - this.frameInstance = frameInstance; - } - - /** - * Position in the current stack: {@code 0} at the top. - */ - public int index() { - return index; - } - - /** - * AST location. - */ - public Node node() { - return node; - } - - /** - * Access to the Truffle {@link Frame}. - */ - public FrameInstance frameInstance() { - return frameInstance; - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpoint.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpoint.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import com.oracle.truffle.api.source.*; - -// TODO (mlvdv) generic? -/** - * A breakpoint associated with a {@linkplain LineLocation source line location}. - * - * @see DebugEngine - */ -public abstract class LineBreakpoint extends Breakpoint { - - LineBreakpoint(BreakpointState state, int groupId, int ignoreCount, boolean isOneShot) { - super(state, groupId, ignoreCount, isOneShot); - } - - /** - * Gets the {@linkplain LineLocation source line location} that specifies where this breakpoint - * will trigger. - */ - public abstract LineLocation getLineLocation(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpointFactory.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpointFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,478 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import static com.oracle.truffle.tools.debug.engine.Breakpoint.BreakpointState.*; - -import java.io.*; -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.tools.*; -import com.oracle.truffle.tools.debug.engine.DebugEngine.BreakpointCallback; -import com.oracle.truffle.tools.debug.engine.DebugEngine.WarningLog; - -//TODO (mlvdv) some common functionality could be factored out of this and TagBreakpointSupport - -/** - * Support class for creating and managing all existing ordinary (user visible) line breakpoints. - *

- * Notes: - *

    - *
  1. Line breakpoints can only be set at nodes tagged as {@link StandardSyntaxTag#STATEMENT}.
  2. - *
  3. A newly created breakpoint looks for probes matching the location, attaches to them if found - * by installing an {@link Instrument} that calls back to the breakpoint.
  4. - *
  5. When Truffle "splits" or otherwise copies an AST, any attached {@link Instrument} will be - * copied along with the rest of the AST and will call back to the same breakpoint.
  6. - *
  7. When notification is received of a new Node being tagged as a statement, and if a - * breakpoint's line location matches the Probe's line location, then the breakpoint will attach a - * new Instrument at the probe to activate the breakpoint at that location.
  8. - *
  9. A breakpoint may have multiple Instruments deployed, one attached to each Probe that matches - * the breakpoint's line location; this might happen when a source is reloaded.
  10. - *
- * - */ -final class LineBreakpointFactory { - - private static final boolean TRACE = false; - private static final PrintStream OUT = System.out; - - private static final String BREAKPOINT_NAME = "LINE BREAKPOINT"; - - private static void trace(String format, Object... args) { - if (TRACE) { - OUT.println(String.format("%s: %s", BREAKPOINT_NAME, String.format(format, args))); - } - } - - private static final Comparator> BREAKPOINT_COMPARATOR = new Comparator>() { - - @Override - public int compare(Entry entry1, Entry entry2) { - final LineLocation line1 = entry1.getKey(); - final LineLocation line2 = entry2.getKey(); - final int nameOrder = line1.getSource().getShortName().compareTo(line2.getSource().getShortName()); - if (nameOrder != 0) { - return nameOrder; - } - return Integer.compare(line1.getLineNumber(), line2.getLineNumber()); - } - }; - - private final DebugExecutionSupport executionSupport; - private final BreakpointCallback breakpointCallback; - private final WarningLog warningLog; - - /** - * Map: Source lines ==> attached breakpoints. There may be no more than one line breakpoint - * associated with a line. - */ - private final Map lineToBreakpoint = new HashMap<>(); - - /** - * A map of {@link LineLocation} to a collection of {@link Probe}s. This list must be - * initialized and filled prior to being used by this class. - */ - private final LineToProbesMap lineToProbesMap; - - /** - * Globally suspends all line breakpoint activity when {@code false}, ignoring whether - * individual breakpoints are enabled. - */ - @CompilationFinal private boolean breakpointsActive = true; - private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active"); - - LineBreakpointFactory(DebugExecutionSupport executionSupport, BreakpointCallback breakpointCallback, WarningLog warningLog) { - this.executionSupport = executionSupport; - this.breakpointCallback = breakpointCallback; - this.warningLog = warningLog; - - lineToProbesMap = new LineToProbesMap(); - lineToProbesMap.install(); - - Probe.addProbeListener(new DefaultProbeListener() { - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - if (tag == StandardSyntaxTag.STATEMENT) { - final SourceSection sourceSection = probe.getProbedSourceSection(); - if (sourceSection != null) { - final LineLocation lineLocation = sourceSection.getLineLocation(); - if (lineLocation != null) { - // A Probe with line location tagged STATEMENT we haven't seen before. - final LineBreakpointImpl breakpoint = lineToBreakpoint.get(lineLocation); - if (breakpoint != null) { - try { - breakpoint.attach(probe); - } catch (DebugException e) { - warningLog.addWarning(BREAKPOINT_NAME + " failure attaching to newly tagged Probe: " + e.getMessage()); - if (TRACE) { - OUT.println(BREAKPOINT_NAME + " failure: " + e.getMessage()); - } - } - } - } - } - } - } - }); - } - - /** - * Globally enables line breakpoint activity; all breakpoints are ignored when set to - * {@code false}. When set to {@code true}, the enabled/disabled status of each breakpoint - * determines whether it will trigger when flow of execution reaches it. - * - * @param breakpointsActive - */ - void setActive(boolean breakpointsActive) { - if (this.breakpointsActive != breakpointsActive) { - breakpointsActiveUnchanged.invalidate(); - this.breakpointsActive = breakpointsActive; - } - } - - /** - * Returns the (not yet disposed) breakpoint by id; null if none. - */ - LineBreakpoint find(long id) { - for (LineBreakpoint breakpoint : lineToBreakpoint.values()) { - if (breakpoint.getId() == id) { - return breakpoint; - } - } - return null; - } - - /** - * Gets all current line breakpoints,regardless of status; sorted and modification safe. - */ - List getAll() { - ArrayList> entries = new ArrayList<>(lineToBreakpoint.entrySet()); - Collections.sort(entries, BREAKPOINT_COMPARATOR); - - final ArrayList breakpoints = new ArrayList<>(entries.size()); - for (Entry entry : entries) { - breakpoints.add(entry.getValue()); - } - return breakpoints; - } - - /** - * Creates a new line breakpoint if one doesn't already exist. If one does exist, then resets - * the ignore count. - * - * @param lineLocation where to set the breakpoint - * @param ignoreCount number of initial hits before the breakpoint starts causing breaks. - * @param oneShot whether the breakpoint should dispose itself after one hit - * @return a possibly new breakpoint - * @throws DebugException if a breakpoint already exists at the location and the ignore count is - * the same - */ - LineBreakpoint create(int groupId, int ignoreCount, LineLocation lineLocation, boolean oneShot) throws DebugException { - - LineBreakpointImpl breakpoint = lineToBreakpoint.get(lineLocation); - - if (breakpoint == null) { - breakpoint = new LineBreakpointImpl(groupId, ignoreCount, lineLocation, oneShot); - - if (TRACE) { - trace("NEW " + breakpoint.getShortDescription()); - } - - lineToBreakpoint.put(lineLocation, breakpoint); - - for (Probe probe : lineToProbesMap.findProbes(lineLocation)) { - if (probe.isTaggedAs(StandardSyntaxTag.STATEMENT)) { - breakpoint.attach(probe); - break; - } - } - } else { - if (ignoreCount == breakpoint.getIgnoreCount()) { - throw new DebugException(BREAKPOINT_NAME + " already set at line " + lineLocation); - } - breakpoint.setIgnoreCount(ignoreCount); - if (TRACE) { - trace("CHANGED ignoreCount %s", breakpoint.getShortDescription()); - } - } - return breakpoint; - } - - /** - * Returns the {@link LineBreakpoint} for a given line. There should only ever be one breakpoint - * per line. - * - * @param lineLocation The {@link LineLocation} to get the breakpoint for. - * @return The breakpoint for the given line. - */ - LineBreakpoint get(LineLocation lineLocation) { - return lineToBreakpoint.get(lineLocation); - } - - /** - * Removes the associated instrumentation for all one-shot breakpoints only. - */ - void disposeOneShots() { - List breakpoints = new ArrayList<>(lineToBreakpoint.values()); - for (LineBreakpointImpl breakpoint : breakpoints) { - if (breakpoint.isOneShot()) { - breakpoint.dispose(); - } - } - } - - /** - * Removes all knowledge of a breakpoint, presumed disposed. - */ - private void forget(LineBreakpointImpl breakpoint) { - lineToBreakpoint.remove(breakpoint.getLineLocation()); - } - - /** - * Concrete representation of a line breakpoint, implemented by attaching an instrument to a - * probe at the designated source location. - */ - private final class LineBreakpointImpl extends LineBreakpoint implements AdvancedInstrumentResultListener { - - private static final String SHOULD_NOT_HAPPEN = "LineBreakpointImpl: should not happen"; - - private final LineLocation lineLocation; - - // Cached assumption that the global status of line breakpoint activity has not changed. - private Assumption breakpointsActiveAssumption; - - // Whether this breakpoint is enable/disabled - @CompilationFinal private boolean isEnabled; - private Assumption enabledUnchangedAssumption; - - private String conditionExpr; - - /** - * The instrument(s) that this breakpoint currently has attached to a {@link Probe}: - * {@code null} if not attached. - */ - private List instruments = new ArrayList<>(); - - public LineBreakpointImpl(int groupId, int ignoreCount, LineLocation lineLocation, boolean oneShot) { - super(ENABLED_UNRESOLVED, groupId, ignoreCount, oneShot); - this.lineLocation = lineLocation; - - this.breakpointsActiveAssumption = LineBreakpointFactory.this.breakpointsActiveUnchanged.getAssumption(); - this.isEnabled = true; - this.enabledUnchangedAssumption = Truffle.getRuntime().createAssumption(BREAKPOINT_NAME + " enabled state unchanged"); - } - - @Override - public boolean isEnabled() { - return isEnabled; - } - - @Override - public void setEnabled(boolean enabled) { - if (enabled != isEnabled) { - switch (getState()) { - case ENABLED: - assert !enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(false); - changeState(DISABLED); - break; - case ENABLED_UNRESOLVED: - assert !enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(false); - changeState(DISABLED_UNRESOLVED); - break; - case DISABLED: - assert enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(true); - changeState(ENABLED); - break; - case DISABLED_UNRESOLVED: - assert enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(true); - changeState(DISABLED_UNRESOLVED); - break; - case DISPOSED: - assert false : "breakpoint disposed"; - break; - default: - assert false : SHOULD_NOT_HAPPEN; - break; - } - } - } - - @Override - public void setCondition(String expr) throws DebugException { - if (this.conditionExpr != null || expr != null) { - // De-instrument the Probes instrumented by this breakpoint - final ArrayList probes = new ArrayList<>(); - for (Instrument instrument : instruments) { - probes.add(instrument.getProbe()); - instrument.dispose(); - } - instruments.clear(); - this.conditionExpr = expr; - // Re-instrument the probes previously instrumented - for (Probe probe : probes) { - attach(probe); - } - } - } - - @Override - public String getCondition() { - return conditionExpr; - } - - @Override - public void dispose() { - if (getState() != DISPOSED) { - for (Instrument instrument : instruments) { - instrument.dispose(); - } - changeState(DISPOSED); - LineBreakpointFactory.this.forget(this); - } - } - - private void attach(Probe newProbe) throws DebugException { - if (getState() == DISPOSED) { - throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); - } - Instrument newInstrument = null; - if (conditionExpr == null) { - newInstrument = Instrument.create(new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME); - } else { - newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME); - } - newProbe.attach(newInstrument); - instruments.add(newInstrument); - changeState(isEnabled ? ENABLED : DISABLED); - } - - private void doSetEnabled(boolean enabled) { - if (this.isEnabled != enabled) { - enabledUnchangedAssumption.invalidate(); - this.isEnabled = enabled; - } - } - - private String getShortDescription() { - return BREAKPOINT_NAME + "@" + getLineLocation().getShortDescription(); - } - - private void changeState(BreakpointState after) { - if (TRACE) { - trace("STATE %s-->%s %s", getState().getName(), after.getName(), getShortDescription()); - } - setState(after); - } - - private void doBreak(Node node, VirtualFrame vFrame) { - if (incrHitCountCheckIgnore()) { - breakpointCallback.haltedAt(node, vFrame.materialize(), BREAKPOINT_NAME); - } - } - - /** - * Receives notification from the attached instrument that execution is about to enter node - * where the breakpoint is set. Designed so that when in the fast path, there is either an - * unconditional "halt" call to the debugger or nothing. - */ - private void nodeEnter(Node astNode, VirtualFrame vFrame) { - - // Deopt if the global active/inactive flag has changed - try { - this.breakpointsActiveAssumption.check(); - } catch (InvalidAssumptionException ex) { - this.breakpointsActiveAssumption = LineBreakpointFactory.this.breakpointsActiveUnchanged.getAssumption(); - } - - // Deopt if the enabled/disabled state of this breakpoint has changed - try { - this.enabledUnchangedAssumption.check(); - } catch (InvalidAssumptionException ex) { - this.enabledUnchangedAssumption = Truffle.getRuntime().createAssumption("LineBreakpoint enabled state unchanged"); - } - - if (LineBreakpointFactory.this.breakpointsActive && this.isEnabled) { - if (isOneShot()) { - dispose(); - } - LineBreakpointImpl.this.doBreak(astNode, vFrame); - } - } - - public void notifyResult(Node node, VirtualFrame vFrame, Object result) { - final boolean condition = (Boolean) result; - if (TRACE) { - trace("breakpoint condition = %b %s", condition, getShortDescription()); - } - if (condition) { - nodeEnter(node, vFrame); - } - } - - @TruffleBoundary - public void notifyFailure(Node node, VirtualFrame vFrame, RuntimeException ex) { - warningLog.addWarning(String.format("Exception in %s: %s", getShortDescription(), ex.getMessage())); - if (TRACE) { - trace("breakpoint failure = %s %s", ex.toString(), getShortDescription()); - } - // Take the breakpoint if evaluation fails. - nodeEnter(node, vFrame); - } - - @Override - public String getLocationDescription() { - return "Line: " + lineLocation.getShortDescription(); - } - - @Override - public LineLocation getLineLocation() { - return lineLocation; - } - - private final class UnconditionalLineBreakInstrumentListener extends DefaultStandardInstrumentListener { - - @Override - public void enter(Probe probe, Node node, VirtualFrame vFrame) { - LineBreakpointImpl.this.nodeEnter(node, vFrame); - } - } - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpoint.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpoint.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import com.oracle.truffle.api.instrument.*; - -// TODO (mlvdv) generic? -/** - * A breakpoint associated with a {@link SyntaxTag}. - * - * @see DebugEngine - */ -public abstract class TagBreakpoint extends Breakpoint { - - TagBreakpoint(BreakpointState state, int groupId, int ignoreCount, boolean isOneShot) { - super(state, groupId, ignoreCount, isOneShot); - } - - /** - * Gets the tag that specifies where this breakpoint will trigger. - */ - public abstract SyntaxTag getTag(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpointFactory.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpointFactory.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,441 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.engine; - -import static com.oracle.truffle.tools.debug.engine.Breakpoint.BreakpointState.*; - -import java.io.*; -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.tools.debug.engine.DebugEngine.BreakpointCallback; -import com.oracle.truffle.tools.debug.engine.DebugEngine.WarningLog; - -// TODO (mlvdv) some common functionality could be factored out of this and LineBreakpointSupport - -/** - * Support class for creating and managing "Tag Breakpoints". A Tag Breakpoint halts execution just - * before reaching any node whose Probe carries a specified {@linkplain SyntaxTag Tag}. - *

- * The {@linkplain Probe#setBeforeTagTrap(SyntaxTagTrap) Tag Trap}, which is built directly into the - * Instrumentation Framework, does the same thing more efficiently, but there may only be one Tag - * Trap active at a time. Any number of tag breakpoints may coexist with the Tag Trap, but it would - * be confusing to have a Tag Breakpoint set for the same Tag as the current Tag Trap. - *

- * Notes: - *

    - *
  1. Only one Tag Breakpoint can be active for a specific {@linkplain SyntaxTag Tag}.
  2. - *
  3. A newly created breakpoint looks for probes matching the tag, attaches to them if found by - * installing an {@link Instrument}.
  4. - *
  5. When Truffle "splits" or otherwise copies an AST, any attached {@link Instrument} will be - * copied along with the rest of the AST and will call back to the same breakpoint.
  6. - *
  7. When notification is received that the breakpoint's Tag has been newly added to a Node, then - * the breakpoint will attach a new Instrument at the probe to activate the breakpoint at that - * location.
  8. - *
  9. A breakpoint may have multiple Instruments deployed, one attached to each Probe that holds - * the breakpoint's tag; this might happen when a source is reloaded.
  10. - *
- */ -final class TagBreakpointFactory { - - private static final boolean TRACE = false; - private static final PrintStream OUT = System.out; - - private static final String BREAKPOINT_NAME = "TAG BREAKPOINT"; - - private static void trace(String format, Object... args) { - if (TRACE) { - OUT.println(String.format("%s: %s", BREAKPOINT_NAME, String.format(format, args))); - } - } - - private static final Comparator> BREAKPOINT_COMPARATOR = new Comparator>() { - - @Override - public int compare(Entry entry1, Entry entry2) { - return entry1.getKey().name().compareTo(entry2.getKey().name()); - } - }; - - private final DebugExecutionSupport executionSupport; - private final BreakpointCallback breakpointCallback; - private final WarningLog warningLog; - - /** - * Map: Tags ==> Tag Breakpoints. There may be no more than one breakpoint per Tag. - */ - private final Map tagToBreakpoint = new HashMap<>(); - - /** - * Globally suspends all line breakpoint activity when {@code false}, ignoring whether - * individual breakpoints are enabled. - */ - @CompilationFinal private boolean breakpointsActive = true; - private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active"); - - TagBreakpointFactory(DebugExecutionSupport executionSupport, BreakpointCallback breakpointCallback, WarningLog warningLog) { - this.executionSupport = executionSupport; - this.breakpointCallback = breakpointCallback; - this.warningLog = warningLog; - - Probe.addProbeListener(new DefaultProbeListener() { - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - final TagBreakpointImpl breakpoint = tagToBreakpoint.get(tag); - if (breakpoint != null) { - try { - breakpoint.attach(probe); - } catch (DebugException e) { - warningLog.addWarning(BREAKPOINT_NAME + " failure attaching to newly tagged Probe: " + e.getMessage()); - if (TRACE) { - OUT.println(BREAKPOINT_NAME + " failure: " + e.getMessage()); - } - } - } - } - }); - } - - /** - * Globally enables tag breakpoint activity; all breakpoints are ignored when set to - * {@code false}. When set to {@code true}, the enabled/disabled status of each breakpoint - * determines whether it will trigger when flow of execution reaches it. - * - * @param breakpointsActive - */ - void setActive(boolean breakpointsActive) { - if (this.breakpointsActive != breakpointsActive) { - breakpointsActiveUnchanged.invalidate(); - this.breakpointsActive = breakpointsActive; - } - } - - /** - * Returns the (not yet disposed) breakpoint by id, if any; null if none. - */ - TagBreakpoint find(long id) { - for (TagBreakpointImpl breakpoint : tagToBreakpoint.values()) { - if (breakpoint.getId() == id) { - return breakpoint; - } - } - return null; - } - - /** - * Gets all current tag breakpoints,regardless of status; sorted and modification safe. - */ - List getAll() { - ArrayList> entries = new ArrayList<>(tagToBreakpoint.entrySet()); - Collections.sort(entries, BREAKPOINT_COMPARATOR); - - final ArrayList breakpoints = new ArrayList<>(entries.size()); - for (Entry entry : entries) { - breakpoints.add(entry.getValue()); - } - return breakpoints; - } - - /** - * Creates a new tag breakpoint if one doesn't already exist. If one does exist, then resets the - * ignore count. - * - * @param tag where to set the breakpoint - * @param ignoreCount number of initial hits before the breakpoint starts causing breaks. - * @param oneShot whether the breakpoint should dispose itself after one hit - * @return a possibly new breakpoint - * @throws DebugException if a breakpoint already exists for the tag and the ignore count is the - * same - */ - TagBreakpoint create(int groupId, int ignoreCount, SyntaxTag tag, boolean oneShot) throws DebugException { - - TagBreakpointImpl breakpoint = tagToBreakpoint.get(tag); - - if (breakpoint == null) { - breakpoint = new TagBreakpointImpl(groupId, ignoreCount, tag, oneShot); - - if (TRACE) { - trace("NEW " + breakpoint.getShortDescription()); - } - - tagToBreakpoint.put(tag, breakpoint); - - for (Probe probe : Probe.findProbesTaggedAs(tag)) { - breakpoint.attach(probe); - } - } else { - if (ignoreCount == breakpoint.getIgnoreCount()) { - throw new DebugException(BREAKPOINT_NAME + " already set for tag " + tag.name()); - } - breakpoint.setIgnoreCount(ignoreCount); - if (TRACE) { - trace("CHANGED ignoreCount %s", breakpoint.getShortDescription()); - } - } - return breakpoint; - } - - /** - * Returns the {@link TagBreakpoint} for a given tag, {@code null} if none. - */ - TagBreakpoint get(SyntaxTag tag) { - return tagToBreakpoint.get(tag); - } - - /** - * Removes the associated instrumentation for all one-shot breakpoints only. - */ - void disposeOneShots() { - List breakpoints = new ArrayList<>(tagToBreakpoint.values()); - for (TagBreakpointImpl breakpoint : breakpoints) { - if (breakpoint.isOneShot()) { - breakpoint.dispose(); - } - } - } - - /** - * Removes all knowledge of a breakpoint, presumed disposed. - */ - private void forget(TagBreakpointImpl breakpoint) { - tagToBreakpoint.remove(breakpoint.getTag()); - } - - /** - * Concrete representation of a line breakpoint, implemented by attaching an instrument to a - * probe at the designated source location. - */ - private final class TagBreakpointImpl extends TagBreakpoint implements AdvancedInstrumentResultListener { - - private static final String SHOULD_NOT_HAPPEN = "TagBreakpointImpl: should not happen"; - - private final SyntaxTag tag; - - // Cached assumption that the global status of tag breakpoint activity has not changed. - private Assumption breakpointsActiveAssumption; - - // Whether this breakpoint is enable/disabled - @CompilationFinal private boolean isEnabled; - private Assumption enabledUnchangedAssumption; - - private String conditionExpr; - - /** - * The instrument(s) that this breakpoint currently has attached to a {@link Probe}: - * {@code null} if not attached. - */ - private List instruments = new ArrayList<>(); - - private TagBreakpointImpl(int groupId, int ignoreCount, SyntaxTag tag, boolean oneShot) { - super(ENABLED, groupId, ignoreCount, oneShot); - this.tag = tag; - this.breakpointsActiveAssumption = TagBreakpointFactory.this.breakpointsActiveUnchanged.getAssumption(); - this.isEnabled = true; - this.enabledUnchangedAssumption = Truffle.getRuntime().createAssumption(BREAKPOINT_NAME + " enabled state unchanged"); - } - - @Override - public boolean isEnabled() { - return isEnabled; - } - - @Override - public void setEnabled(boolean enabled) { - // Tag Breakpoints are never unresolved - if (enabled != isEnabled) { - switch (getState()) { - case ENABLED: - assert !enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(false); - changeState(DISABLED); - break; - case DISABLED: - assert enabled : SHOULD_NOT_HAPPEN; - doSetEnabled(true); - changeState(ENABLED); - break; - case DISPOSED: - assert false : "breakpoint disposed"; - break; - case ENABLED_UNRESOLVED: - case DISABLED_UNRESOLVED: - default: - assert false : SHOULD_NOT_HAPPEN; - break; - } - } - } - - @Override - public void setCondition(String expr) throws DebugException { - if (this.conditionExpr != null || expr != null) { - // De-instrument the Probes instrumented by this breakpoint - final ArrayList probes = new ArrayList<>(); - for (Instrument instrument : instruments) { - probes.add(instrument.getProbe()); - instrument.dispose(); - } - instruments.clear(); - this.conditionExpr = expr; - // Re-instrument the probes previously instrumented - for (Probe probe : probes) { - attach(probe); - } - } - } - - @Override - public String getCondition() { - return conditionExpr; - } - - @Override - public void dispose() { - if (getState() != DISPOSED) { - for (Instrument instrument : instruments) { - instrument.dispose(); - } - changeState(DISPOSED); - TagBreakpointFactory.this.forget(this); - } - } - - private void attach(Probe newProbe) throws DebugException { - if (getState() == DISPOSED) { - throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); - } - Instrument newInstrument = null; - if (conditionExpr == null) { - newInstrument = Instrument.create(new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME); - } else { - newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME); - } - newProbe.attach(newInstrument); - instruments.add(newInstrument); - changeState(isEnabled ? ENABLED : DISABLED); - } - - private void doSetEnabled(boolean enabled) { - if (this.isEnabled != enabled) { - enabledUnchangedAssumption.invalidate(); - this.isEnabled = enabled; - } - } - - private String getShortDescription() { - return BREAKPOINT_NAME + "@" + tag.name(); - } - - private void changeState(BreakpointState after) { - if (TRACE) { - trace("STATE %s-->%s %s", getState().getName(), after.getName(), getShortDescription()); - } - setState(after); - } - - private void doBreak(Node node, VirtualFrame vFrame) { - if (incrHitCountCheckIgnore()) { - breakpointCallback.haltedAt(node, vFrame.materialize(), BREAKPOINT_NAME); - } - } - - /** - * Receives notification from the attached instrument that execution is about to enter node - * where the breakpoint is set. Designed so that when in the fast path, there is either an - * unconditional "halt" call to the debugger or nothing. - */ - private void nodeEnter(Node astNode, VirtualFrame vFrame) { - - // Deopt if the global active/inactive flag has changed - try { - this.breakpointsActiveAssumption.check(); - } catch (InvalidAssumptionException ex) { - this.breakpointsActiveAssumption = TagBreakpointFactory.this.breakpointsActiveUnchanged.getAssumption(); - } - - // Deopt if the enabled/disabled state of this breakpoint has changed - try { - this.enabledUnchangedAssumption.check(); - } catch (InvalidAssumptionException ex) { - this.enabledUnchangedAssumption = Truffle.getRuntime().createAssumption("LineBreakpoint enabled state unchanged"); - } - - if (TagBreakpointFactory.this.breakpointsActive && this.isEnabled) { - if (isOneShot()) { - dispose(); - } - TagBreakpointImpl.this.doBreak(astNode, vFrame); - } - - } - - public void notifyResult(Node node, VirtualFrame vFrame, Object result) { - final boolean condition = (Boolean) result; - if (TRACE) { - trace("breakpoint condition = %b %s", condition, getShortDescription()); - } - if (condition) { - nodeEnter(node, vFrame); - } - } - - public void notifyFailure(Node node, VirtualFrame vFrame, RuntimeException ex) { - warningLog.addWarning(String.format("Exception in %s: %s", getShortDescription(), ex.getMessage())); - if (TRACE) { - trace("breakpoint failure = %s %s", ex.toString(), getShortDescription()); - } - // Take the breakpoint if evaluation fails. - nodeEnter(node, vFrame); - } - - @Override - public String getLocationDescription() { - return "Tag " + tag.name(); - } - - @Override - public SyntaxTag getTag() { - return tag; - } - - private final class UnconditionalTagBreakInstrumentListener extends DefaultStandardInstrumentListener { - - @Override - public void enter(Probe probe, Node node, VirtualFrame vFrame) { - TagBreakpointImpl.this.nodeEnter(node, vFrame); - } - } - - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/package-info.java --- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/package-info.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -/** - * This package contains the shared (language-agnostic) support for implementing debuggers - * that work with Truffle-implemented languages. - *

- * This implementation is made possible by the general purpose Instrumentation Framework built - * into the Truffle platform. Some online documentation for the Instrumentation Framework is available - * online: - * - * https://wiki.openjdk.java.net/display/Graal/Instrumentation+API - * - *

- * Debugging services for a Truffle-implemented language are provided by creating an instance - * of {@link com.oracle.truffle.tools.debug.engine.DebugEngine} specialized for a specific language. The DebugEngine can: - *

    - *
  • Load and run sources in the language
  • - *
  • Set breakpoints possibly with conditions and other attributes, on source lines
  • - *
  • Navigate by Continue, StepIn, StepOver, or StepOut
  • - *
  • Examine the execution stack
  • - *
  • Examine the contents of a stack frame
  • - *
  • Evaluate a code fragment in the context of a stack frame
  • - *
- *

- * Specialization of the DebugEngine for a Truffle-implemented language takes several forms: - *

    - *
  1. A specification from the language implementor that adds Instrumentation "tags" to the nodes - * that a debugger should know about, for example Statements, Calls, and Throws
  2. - *
  3. Methods to run programs/scripts generally, and more specifically run text fragments in the context of - * a particular frame/Node in a halted Truffle execution
  4. - *
  5. Utility methods, such as providing textual displays of Objects that represent values in the language
  6. - *
- *

- * Note: Both the functionality and API for this package are under active development. - *

- * @see com.oracle.truffle.api.instrument - */ -package com.oracle.truffle.tools.debug.engine; - diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLClient.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLClient.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell; - -/** - * The client side of a simple message-based protocol for a possibly remote language - * Read-Eval-Print-Loop. - */ -public interface REPLClient { - - /** - * Accepts a reply from the server; there may be more than one reply in response to a request. - */ - REPLMessage receive(REPLMessage reply); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLMessage.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLMessage.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell; - -import java.io.*; -import java.util.*; -import java.util.Map.Entry; - -/** - * A message for communication between a Read-Eval-Print-Loop server associated with a language - * implementation and a possibly remote client. - * - * @see REPLClient - * @see REPLServer - */ -public final class REPLMessage { - - // Some standard keys and values - public static final String AST = "ast"; - public static final String AST_DEPTH = "show-max-depth"; - public static final String BACKTRACE = "backtrace"; - public static final String BREAK_AT_LINE = "break-at-line"; - public static final String BREAK_AT_LINE_ONCE = "break-at-line-once"; - public static final String BREAK_AT_THROW = "break-at-throw"; - public static final String BREAK_AT_THROW_ONCE = "break-at-throw-once"; - public static final String BREAKPOINT_CONDITION = "breakpoint-condition"; - public static final String BREAKPOINT_GROUP_ID = "breakpoint-group-id"; - public static final String BREAKPOINT_HIT_COUNT = "breakpoint-hit-count"; - public static final String BREAKPOINT_ID = "breakpoint-id"; - public static final String BREAKPOINT_IGNORE_COUNT = "breakpoint-ignore-count"; - public static final String BREAKPOINT_INFO = "breakpoint-info"; - public static final String BREAKPOINT_STATE = "breakpoint-state"; - public static final String CLEAR_BREAK = "clear-breakpoint"; - public static final String CODE = "code"; - public static final String CONTINUE = "continue"; - public static final String DEBUG_LEVEL = "debug-level"; - public static final String DELETE_BREAK = "delete-breakpoint"; - public static final String DISABLE_BREAK = "disable-breakpoint"; - public static final String DISPLAY_MSG = "displayable-message"; - public static final String DOWN = "down"; - public static final String ENABLE_BREAK = "enable-breakpoint"; - public static final String EVAL = "eval"; - public static final String FAILED = "failed"; - public static final String FILE = "file"; - public static final String FILE_PATH = "path"; - public static final String FRAME = "frame"; - public static final String FRAME_INFO = "frame-info"; - public static final String FRAME_NUMBER = "frame-number"; - public static final String INFO = "info"; - public static final String INFO_KEY = "info-key"; - public static final String INFO_VALUE = "info-value"; - public static final String KILL = "kill"; - public static final String LANGUAGE = "language"; - public static final String LINE_NUMBER = "line-number"; - public static final String LIST = "list"; - public static final String LOAD_RUN = "load-run-source"; - public static final String LOAD_STEP = "load-step-into-source"; - public static final String METHOD_NAME = "method-name"; - public static final String OP = "op"; - public static final String OPTION = "option"; - public static final String QUIT = "quit"; - public static final String REPEAT = "repeat"; - public static final String SET = "set"; - public static final String SET_BREAK_CONDITION = "set-breakpoint-condition"; - public static final String SOURCE_LINE_TEXT = "source-line-text"; - public static final String SOURCE_LOCATION = "source-location"; - public static final String SOURCE_NAME = "source-name"; - public static final String SOURCE_TEXT = "source-text"; - public static final String STACK_SIZE = "stack-size"; - public static final String STATUS = "status"; - public static final String STEP_INTO = "step-into"; - public static final String STEP_OUT = "step-out"; - public static final String STEP_OVER = "step-over"; - public static final String STOPPED = "stopped"; - public static final String SUB = "sub"; - public static final String SUBTREE = "subtree"; - public static final String SUCCEEDED = "succeeded"; - public static final String TOPIC = "topic"; - public static final String TRUFFLE = "truffle"; - public static final String TRUFFLE_AST = "truffle-ast"; - public static final String TRUFFLE_NODE = "truffle-node"; - public static final String TRUFFLE_SUBTREE = "truffle-subtree"; - public static final String UNSET_BREAK_CONDITION = "unset-breakpoint-condition"; - public static final String UP = "up"; - public static final String VALUE = "value"; - public static final String WARNINGS = "warnings"; - private final Map map; - - /** - * Creates an empty REPL message. - */ - public REPLMessage() { - this.map = new TreeMap<>(); - } - - /** - * Creates a REPL message with an initial entry. - */ - public REPLMessage(String key, String value) { - this(); - map.put(key, value); - } - - public REPLMessage(REPLMessage message) { - this.map = new TreeMap<>(message.map); - } - - public String get(String key) { - return map.get(key); - } - - /** - * Returns the specified key value as an integer; {@code null} if missing or non-numeric. - */ - public Integer getIntValue(String key) { - final String value = map.get(key); - if (value != null) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - - } - } - return null; - } - - public String put(String key, String value) { - return map.put(key, value); - } - - public String remove(String key) { - return map.remove(key); - } - - public Set keys() { - return map.keySet(); - } - - public void print(PrintStream out, String linePrefix) { - map.keySet(); - - for (Entry entry : map.entrySet()) { - String value = entry.getValue(); - if (value != null && value.length() > 50) { - value = value.substring(0, 50) + " ..."; - } - out.println(linePrefix + entry.getKey() + " = \"" + value + "\""); - } - } -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLServer.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/REPLServer.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell; - -/** - * The server side of a simple message-based protocol for a possibly remote language - * Read-Eval-Print-Loop. - */ -public interface REPLServer { - - /** - * Starts up a server; status returned in a message. - */ - REPLMessage start(); - - /** - * Ask the server to handle a request. Return a non-empty array of messages to simulate remote - * operation where the protocol has possibly multiple messages being returned asynchronously in - * response to each request. - */ - REPLMessage[] receive(REPLMessage request); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLClientContext.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLClientContext.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -import java.util.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.tools.debug.shell.*; - -/** - * Client context for interaction with a program halted by the {@link REPLServer}. - */ -public interface REPLClientContext { - - /** - * The source code halted in this context. - */ - Source source(); - - /** - * The 1-based line at which execution is halted in this context; 0 means unknown. - */ - int lineNumber(); - - /** - * The Truffle stack where execution is halted in this context. - */ - List frames(); - - /** - * The nesting level of the execution context: 0 means evaluating shell commands outside any - * executing program. - */ - int level(); - - /** - * The source currently selected by the user; defaults to where halted. - */ - Source getSelectedSource(); - - /** - * The frame number in this execution context currently selected by the user; defaults to 0. - */ - int getSelectedFrameNumber(); - - /** - * Issue a command to the REPLServer that - *

    - *
  • can be specified by a single "op",
  • - *
  • produces information in the form of a single string, and
  • - *
  • has no effect on the execution state.
  • - *
- */ - String stringQuery(String op); - - /** - * Sets a new "default" frame number for frame-related commands. - */ - void selectFrameNumber(int frameNumber); - - /** - * Sends an information message. - */ - void displayInfo(String message); - - void displayStack(); - - /** - * Send a message related to handling a command in this context. - */ - void displayReply(String message); - - /** - * Send a message related to failure while handling a command in this context. - */ - void displayFailReply(String message); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLCommand.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLCommand.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -// TODO (mlvdv) write a real command line parser -abstract class REPLCommand { - - private final String command; - private final String abbreviation; - private final String description; - - public REPLCommand(String command, String abbreviation, String description) { - this.command = command; - this.abbreviation = abbreviation; - this.description = description; - } - - public final String getCommand() { - return command; - } - - public final String getAbbreviation() { - return abbreviation; - } - - public final String getDescription() { - return description; - } - - public String[] getHelp() { - return new String[]{getCommand() + ": " + getDescription()}; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLContinueException.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLContinueException.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -class REPLContinueException extends RuntimeException { - - private static final long serialVersionUID = 4763527450877123326L; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLFrame.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLFrame.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -/** - * Information about a stack frame in the current {@link REPLClientContext}. - */ -interface REPLFrame { - - /** - * Index of the frame. - */ - int index(); - - /** - * File path; null if unknown. - */ - String locationFilePath(); - - /** - * Line number of frame location; null if unknown. - */ - Integer locationLineNumber(); - - /** - * Short description of the code location. - */ - String locationDescription(); - - /** - * Name of the method body containing the location. - */ - String name(); - - /** - * The line of text at the code location. - */ - String sourceLineText(); - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLRemoteCommand.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLRemoteCommand.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,696 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.tools.debug.shell.*; - -// TODO (mlvdv) write a real command line parser -public abstract class REPLRemoteCommand extends REPLCommand { - - public REPLRemoteCommand(String command, String abbreviation, String description) { - super(command, abbreviation, description); - } - - protected abstract REPLMessage createRequest(REPLClientContext context, String[] args); - - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - final String result = firstReply.get(REPLMessage.DISPLAY_MSG); - context.displayFailReply(result != null ? result : firstReply.toString()); - } else { - final String result = firstReply.get(REPLMessage.DISPLAY_MSG); - context.displayReply(result != null ? result : firstReply.toString()); - } - - for (int i = 1; i < replies.length; i++) { - REPLMessage reply = replies[i]; - final String result = reply.get(REPLMessage.DISPLAY_MSG); - context.displayInfo(result != null ? result : reply.toString()); - } - } - - public static final REPLRemoteCommand BREAK_AT_LINE_CMD = new REPLRemoteCommand("break-at-line", "break", "Set a breakpoint") { - - private final String[] help = {"break [ignore=] : set breakpoint at line in current file", "break : [ignore=] : set breakpoint at line in ", - " optionally ignore first hits (default 0)"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - try { - final REPLineLocation lineLocation = REPLineLocation.parse(context, args); - final REPLMessage requestMessage = lineLocation.createMessage(REPLMessage.BREAK_AT_LINE); - int ignoreCount = 0; - if (args.length > 2) { - final String ignoreText = args[2]; - if (ignoreText.equals("ignore")) { - throw new IllegalArgumentException("No ignore count specified"); - } - final String[] split = ignoreText.split("="); - if (split.length == 2 && split[0].equals("ignore")) { - try { - ignoreCount = Integer.parseInt(split[1]); - if (ignoreCount < 0) { - throw new IllegalArgumentException("Illegal ignore count: " + split[1]); - } - } catch (NumberFormatException e) { - throw new IllegalArgumentException("No ignore count specified"); - } - } else { - throw new IllegalArgumentException("Unrecognized argument \"" + ignoreText + "\""); - } - } - requestMessage.put(REPLMessage.BREAKPOINT_IGNORE_COUNT, Integer.toString(ignoreCount)); - return requestMessage; - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final String number = firstReply.get(REPLMessage.BREAKPOINT_ID); - final String fileName = firstReply.get(REPLMessage.SOURCE_NAME); - final String lineNumber = firstReply.get(REPLMessage.LINE_NUMBER); - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + number + " set at " + fileName + ":" + lineNumber); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand BREAK_AT_LINE_ONCE_CMD = new REPLRemoteCommand("break-at-line-once", "break1", "Set a one-shot breakpoint") { - - private final String[] help = {"break : set one-shot breakpoint at line in current file", "break :: set one-shot breakpoint at line in current file"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - try { - return REPLineLocation.parse(context, args).createMessage(REPLMessage.BREAK_AT_LINE_ONCE); - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final String fileName = firstReply.get(REPLMessage.SOURCE_NAME); - final String lineNumber = firstReply.get(REPLMessage.LINE_NUMBER); - firstReply.put(REPLMessage.DISPLAY_MSG, "one-shot breakpoint set at " + fileName + ":" + lineNumber); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand BREAK_AT_THROW_CMD = new REPLRemoteCommand("break-at-throw", "breakthrow", "Break at any throw") { - - private final String[] help = {"break-at-throw: set breakpoint on any throw"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.BREAK_AT_THROW); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint at any throw set"); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand BREAK_AT_THROW_ONCE_CMD = new REPLRemoteCommand("break-at-throw-once", "break1throw", "Break once at any throw") { - - private final String[] help = {"break-at-throw: set one-short breakpoint on any throw"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.BREAK_AT_THROW_ONCE); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - firstReply.put(REPLMessage.DISPLAY_MSG, "one-shot breakpoint at any throw set"); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand CLEAR_BREAK_CMD = new REPLRemoteCommand("clear", null, "Clear a breakpoint") { - - private final String[] help = {"clear : clear breakpoint number "}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length == 1) { - context.displayFailReply("breakpoint number not speciified: \"break \""); - } else if (args.length > 2) { - context.displayFailReply("breakpoint number not understood: \"break \""); - } else { - try { - final int breakpointNumber = Integer.parseInt(args[1]); - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.CLEAR_BREAK); - request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); - return request; - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " cleared"); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand CONDITION_BREAK_CMD = new REPLRemoteCommand("cond", null, "Set new condition on a breakpoint") { - - private final String[] help = {"cond [expr]: sets new condition on breakpoint number ; make unconditional if no [expr]"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length == 1) { - context.displayFailReply("breakpoint number not speciified: \"cond \""); - } else { - try { - final int breakpointNumber = Integer.parseInt(args[1]); - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); - if (args.length == 2) { - request.put(REPLMessage.OP, REPLMessage.UNSET_BREAK_CONDITION); - } else { - final StringBuilder exprBuilder = new StringBuilder(); - for (int i = 2; i < args.length; i++) { - exprBuilder.append(args[i]).append(" "); - } - request.put(REPLMessage.BREAKPOINT_CONDITION, exprBuilder.toString().trim()); - request.put(REPLMessage.OP, REPLMessage.SET_BREAK_CONDITION); - } - return request; - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); - final String condition = firstReply.get(REPLMessage.BREAKPOINT_CONDITION); - if (condition == null) { - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " condition cleared"); - } else { - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " condition=\"" + condition + "\""); - } - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand CONTINUE_CMD = new REPLRemoteCommand("continue", "c", "Continue execution") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.CONTINUE); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - - throw new REPLContinueException(); - - } - }; - - public static final REPLRemoteCommand DELETE_CMD = new REPLRemoteCommand("delete", "d", "Delete all breakpoints") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.DELETE_BREAK); - return request; - } - }; - - public static final REPLRemoteCommand DISABLE_CMD = new REPLRemoteCommand("disable", null, "Disable a breakpoint") { - - private final String[] help = {"disable : disable breakpoint number "}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length == 1) { - context.displayFailReply("breakpoint number not speciified: \"disable \""); - } else if (args.length > 2) { - context.displayFailReply("breakpoint number not understood: \"disable \""); - } else { - try { - final int breakpointNumber = Integer.parseInt(args[1]); - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.DISABLE_BREAK); - request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); - return request; - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " disabled"); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand DOWN_CMD = new REPLRemoteCommand("down", null, "Move down a stack frame") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final List frames = context.frames(); - final int newFrameSelection = context.getSelectedFrameNumber() + 1; - if (newFrameSelection > frames.size() - 1) { - context.displayFailReply("at bottom of stack"); - return null; - } - context.selectFrameNumber(newFrameSelection); - return FRAME_CMD.createRequest(context, Arrays.copyOfRange(args, 0, 0)); - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - final String result = firstReply.get(REPLMessage.DISPLAY_MSG); - context.displayFailReply(result != null ? result : firstReply.toString()); - } else { - context.displayStack(); - } - } - }; - - public static final REPLRemoteCommand ENABLE_CMD = new REPLRemoteCommand("enable", null, "Enable a breakpoint") { - - private final String[] help = {"enable : enable breakpoint number "}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length == 1) { - context.displayFailReply("breakpoint number not speciified: \"enable \""); - } else if (args.length > 2) { - context.displayFailReply("breakpoint number not understood: \"enable \""); - } else { - try { - final int breakpointNumber = Integer.parseInt(args[1]); - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.ENABLE_BREAK); - request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); - return request; - } catch (IllegalArgumentException ex) { - context.displayFailReply(ex.getMessage()); - } - } - return null; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); - firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " enabled"); - } - super.processReply(context, replies); - } - }; - - public static final REPLRemoteCommand FRAME_CMD = new REPLRemoteCommand("frame", null, "Display a stack frame") { - - private final String[] help = {"frame : display currently selected frame", "frame : display frame "}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.FRAME); - - int frameNumber = context.getSelectedFrameNumber(); - if (args.length > 1) { - if (args.length == 2) { - try { - frameNumber = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Unrecognized argument \"" + args[1] + "\""); - } - } else { - throw new IllegalArgumentException("Unrecognized argument \"" + args[2] + "\""); - } - } - request.put(REPLMessage.FRAME_NUMBER, Integer.toString(frameNumber)); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - context.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); - } else { - Integer frameNumber = replies[0].getIntValue(REPLMessage.FRAME_NUMBER); - context.selectFrameNumber(frameNumber); - context.displayReply("Frame " + frameNumber + ":"); - for (REPLMessage message : replies) { - for (String line : message.get(REPLMessage.DISPLAY_MSG).split("\n")) { - context.displayInfo(line); - } - } - } - } - }; - - public static final REPLRemoteCommand KILL_CMD = new REPLRemoteCommand("kill", null, "Stop program execution") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, "kill"); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { - context.displayReply(replies[0].get(REPLMessage.DISPLAY_MSG)); - } else { - context.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); - } - } - }; - - public static final REPLRemoteCommand LOAD_RUN_CMD = new REPLRemoteCommand("load-run", "loadr", "Load and run a source") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - Source runSource = null; - if (args.length == 1) { - runSource = context.getSelectedSource(); - if (runSource == null) { - context.displayFailReply("No file selected"); - return null; - } - } else { - try { - runSource = Source.fromFileName(args[1]); - } catch (IOException e) { - context.displayFailReply("Can't find file: " + args[1]); - return null; - } - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.LOAD_RUN); - request.put(REPLMessage.SOURCE_NAME, runSource.getPath()); - return request; - } - }; - - public static final REPLRemoteCommand LOAD_STEP_CMD = new REPLRemoteCommand("load-step", "loads", "Load and step into a source") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - Source runSource = null; - if (args.length == 1) { - runSource = context.getSelectedSource(); - if (runSource == null) { - context.displayFailReply("No file selected"); - return null; - } - } else { - try { - runSource = Source.fromFileName(args[1]); - } catch (IOException e) { - context.displayFailReply("Can't find file: " + args[1]); - return null; - } - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.LOAD_STEP); - request.put(REPLMessage.SOURCE_NAME, runSource.getPath()); - return request; - } - }; - - public static final REPLRemoteCommand STEP_INTO_CMD = new REPLRemoteCommand("step", "s", "(StepInto) next statement, going into functions.") { - - @Override - public String[] getHelp() { - return new String[]{"step into: step to next statement (into calls)", "step : step to nth next statement (into calls)"}; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.STEP_INTO); - - if (args.length >= 2) { - final String nText = args[1]; - try { - final int nSteps = Integer.parseInt(nText); - if (nSteps > 0) { - request.put(REPLMessage.REPEAT, Integer.toString(nSteps)); - } else { - return null; - } - } catch (NumberFormatException e) { - context.displayFailReply("Step into count \"" + nText + "\" not recognized"); - return null; - } - } - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - - throw new REPLContinueException(); - } - }; - - public static final REPLRemoteCommand STEP_OUT_CMD = new REPLRemoteCommand("finish", null, "(StepOut) continue to end of function") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.STEP_OUT); - - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - - throw new REPLContinueException(); - } - }; - - public static final REPLRemoteCommand STEP_OVER_CMD = new REPLRemoteCommand("next", "n", "(StepOver) execute next line of code, not into functions.") { - - @Override - public String[] getHelp() { - return new String[]{"next: (StepOver) execute next line of code, not into functions.", "next : (StepOver) execute to nth next statement (not counting into functions)"}; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.STEP_OVER); - - if (args.length >= 2) { - final String nText = args[1]; - try { - final int nSteps = Integer.parseInt(nText); - if (nSteps > 0) { - request.put(REPLMessage.REPEAT, Integer.toString(nSteps)); - } else { - return null; - } - } catch (NumberFormatException e) { - context.displayFailReply("Next count \"" + nText + "\" not recognized"); - return null; - } - } - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - - throw new REPLContinueException(); - } - }; - - public static final REPLRemoteCommand UP_CMD = new REPLRemoteCommand("up", null, "Move up a stack frame") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (context.level() == 0) { - context.displayFailReply("no active execution"); - return null; - } - final int newFrameSelection = context.getSelectedFrameNumber() - 1; - if (newFrameSelection < 0) { - context.displayFailReply("at top of stack"); - return null; - } - context.selectFrameNumber(newFrameSelection); - return FRAME_CMD.createRequest(context, Arrays.copyOfRange(args, 0, 0)); - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - final String result = firstReply.get(REPLMessage.DISPLAY_MSG); - context.displayFailReply(result != null ? result : firstReply.toString()); - } else { - context.displayStack(); - } - } - }; - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLineLocation.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLineLocation.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -import java.io.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.tools.debug.shell.*; - -final class REPLineLocation { - - private final Source source; - private final int lineNumber; - - /** - * Attempts to extract description of a source line from {@code arg[1]}, either - * ":" or just "". - */ - static REPLineLocation parse(REPLClientContext context, String[] args) throws IllegalArgumentException { - if (args.length == 1) { - throw new IllegalArgumentException("no location specified"); - } - - Source source = null; - int lineNumber = -1; - String lineNumberText = null; - - final String[] split = args[1].split(":"); - if (split.length == 1) { - // Specification only has one part; it should be a line number - lineNumberText = split[0]; - try { - lineNumber = Integer.parseInt(lineNumberText); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("no line number specified"); - } - // If only line number specified, then there must be a selected file - final Source selectedSource = context.getSelectedSource(); - if (selectedSource == null) { - throw new IllegalArgumentException("no selected file set"); - } - source = selectedSource; - - } else { - final String fileName = split[0]; - lineNumberText = split[1]; - try { - source = Source.fromFileName(fileName); - } catch (IOException e1) { - throw new IllegalArgumentException("Can't find file \"" + fileName + "\""); - } - try { - lineNumber = Integer.parseInt(lineNumberText); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid line number \"" + lineNumberText + "\""); - } - if (lineNumber <= 0) { - throw new IllegalArgumentException("Invalid line number \"" + lineNumberText + "\""); - } - } - - return new REPLineLocation(source, lineNumber); - } - - REPLineLocation(Source source, int lineNumber) { - this.source = source; - this.lineNumber = lineNumber; - } - - public Source getSource() { - return source; - } - - public int getLineNumber() { - return lineNumber; - } - - /** - * Creates a message containing an "op" and a line location. - * - * @param op the operation to be performed on this location - */ - public REPLMessage createMessage(String op) { - final REPLMessage msg = new REPLMessage(REPLMessage.OP, op); - msg.put(REPLMessage.SOURCE_NAME, source.getShortName()); - msg.put(REPLMessage.FILE_PATH, source.getPath()); - msg.put(REPLMessage.LINE_NUMBER, Integer.toString(lineNumber)); - return msg; - } - -} diff -r 2a5011c7e641 -r 9c8c0937da41 graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java --- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java Wed Jun 17 10:01:47 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1397 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.debug.shell.client; - -import java.io.*; -import java.util.*; - -import jline.console.*; - -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.tools.debug.shell.*; - -/** - * A very simple line-oriented, language-agnostic debugging client shell: the first step toward a - * general, extensible debugging framework designed to be adapted for remote debugging. - *

- * The architecture of this debugging framework is modeled loosely on nREPL, a network REPL developed by the Clojure - * community with a focus on generality: - *

    - *
  • Client and (possibly remote) server communicate via messages carried over some - * transport;
  • - *
  • A message is a map of key/value pairs;
  • - *
  • Keys and values are strings;
  • - *
  • The client sends messages as requests to a server;
  • - *
  • A server dispatches each incoming request to an appropriate handler that takes - * appropriate action and responds to the client with one or more messages; and
  • - *
  • Many implementations of the transport are possible.
  • - *
- *

- * Compromises: - *

- * In order to get - *

    - *
  1. A debugging session should start from this shell, but there is no machinery in place for - * doing that; instead, an entry into the language implementation creates both the server and this - * shell;
  2. - *
  3. The current startup sequence is based on method calls, not messages;
  4. - *
  5. Only a very few request types and keys are implemented, omitting for example request and - * session ids;
  6. - *
  7. Message passing is synchronous and "transported" via method calls;
  8. - *
  9. Asynchrony is emulated by having each call to the server pass only a message, and by having - * the server return only a list of messages.
  10. - *
- * - * @see REPLServer - * @see REPLMessage - */ -public class SimpleREPLClient implements REPLClient { - - private static final String REPLY_PREFIX = "==> "; - private static final String FAIL_PREFIX = "**> "; - private static final String WARNING_PREFIX = "!!> "; - private static final String TRACE_PREFIX = ">>> "; - private static final String[] NULL_ARGS = new String[0]; - - static final String INFO_LINE_FORMAT = " %s\n"; - static final String CODE_LINE_FORMAT = " %3d %s\n"; - static final String CODE_LINE_BREAK_FORMAT = "--> %3d %s\n"; - - private static final String STACK_FRAME_FORMAT = " %3d: at %s in %s line =\"%s\"\n"; - private static final String STACK_FRAME_SELECTED_FORMAT = "==> %3d: at %s in %s line =\"%s\"\n"; - - private final String languageName; - - // Top level commands - private final Map commandMap = new HashMap<>(); - private final Collection commandNames = new TreeSet<>(); - - // Local options - private final Map localOptions = new HashMap<>(); - private final Collection optionNames = new TreeSet<>(); - - // Current local context - ClientContextImpl clientContext; - - // Cheating for the prototype; prototype startup now happens from the language server. - // So this isn't used. - public static void main(String[] args) { - final SimpleREPLClient repl = new SimpleREPLClient(null, null); - repl.start(); - } - - private final ConsoleReader reader; - - private final PrintStream writer; - - private final REPLServer replServer; - - private final LocalOption astDepthOption = new IntegerOption(9, "astdepth", "default depth for AST display"); - - private final LocalOption autoWhereOption = new BooleanOption(true, "autowhere", "run the \"where\" command after each navigation"); - - private final LocalOption autoNodeOption = new BooleanOption(false, "autonode", "run the \"truffle node\" command after each navigation"); - - private final LocalOption autoSubtreeOption = new BooleanOption(false, "autosubtree", "run the \"truffle subtree\" command after each navigation"); - - private final LocalOption autoASTOption = new BooleanOption(false, "autoast", "run the \"truffle ast\" command after each navigation"); - - private final LocalOption listSizeOption = new IntegerOption(25, "listsize", "default number of lines to list"); - - private final LocalOption traceMessagesOption = new BooleanOption(false, "tracemessages", "trace REPL messages between client and server"); - - private final LocalOption verboseBreakpointInfoOption = new BooleanOption(true, "verbosebreakpointinfo", "\"info breakpoint\" displays more info"); - - private void addOption(LocalOption localOption) { - final String optionName = localOption.getName(); - localOptions.put(optionName, localOption); - optionNames.add(optionName); - } - - /** - * Non-null when the user has named a file other than where halted, providing context for - * commands such as "break"; if no explicit selection, then defaults to where halted. This is - * session state, so it persists across halting contexts. - */ - private Source selectedSource = null; - - public SimpleREPLClient(String languageName, REPLServer replServer) { - this.languageName = languageName; - this.replServer = replServer; - this.writer = System.out; - try { - this.reader = new ConsoleReader(); - } catch (IOException e) { - throw new RuntimeException("Unable to create console " + e); - } - - addCommand(backtraceCommand); - addCommand(REPLRemoteCommand.BREAK_AT_LINE_CMD); - addCommand(REPLRemoteCommand.BREAK_AT_LINE_ONCE_CMD); - addCommand(REPLRemoteCommand.BREAK_AT_THROW_CMD); - addCommand(REPLRemoteCommand.BREAK_AT_THROW_ONCE_CMD); - addCommand(REPLRemoteCommand.CLEAR_BREAK_CMD); - addCommand(REPLRemoteCommand.CONDITION_BREAK_CMD); - addCommand(REPLRemoteCommand.CONTINUE_CMD); - addCommand(REPLRemoteCommand.DELETE_CMD); - addCommand(REPLRemoteCommand.DISABLE_CMD); - addCommand(REPLRemoteCommand.DOWN_CMD); - addCommand(REPLRemoteCommand.ENABLE_CMD); - addCommand(evalCommand); - addCommand(fileCommand); - addCommand(REPLRemoteCommand.FRAME_CMD); - addCommand(helpCommand); - addCommand(infoCommand); - addCommand(REPLRemoteCommand.KILL_CMD); - addCommand(listCommand); - addCommand(REPLRemoteCommand.LOAD_RUN_CMD); - addCommand(REPLRemoteCommand.LOAD_STEP_CMD); - addCommand(quitCommand); - addCommand(setCommand); - addCommand(REPLRemoteCommand.STEP_INTO_CMD); - addCommand(REPLRemoteCommand.STEP_OUT_CMD); - addCommand(REPLRemoteCommand.STEP_OVER_CMD); - addCommand(truffleCommand); - addCommand(REPLRemoteCommand.UP_CMD); - addCommand(whereCommand); - - infoCommand.addCommand(infoBreakCommand); - infoCommand.addCommand(infoLanguageCommand); - infoCommand.addCommand(infoSetCommand); - - truffleCommand.addCommand(truffleASTCommand); - truffleCommand.addCommand(truffleNodeCommand); - truffleCommand.addCommand(truffleSubtreeCommand); - - addOption(astDepthOption); - addOption(autoASTOption); - addOption(autoNodeOption); - addOption(autoSubtreeOption); - addOption(autoWhereOption); - addOption(listSizeOption); - addOption(traceMessagesOption); - addOption(verboseBreakpointInfoOption); - } - - public void start() { - - REPLMessage startReply = replServer.start(); - - if (startReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - clientContext.displayFailReply(startReply.get(REPLMessage.DISPLAY_MSG)); - throw new RuntimeException("Can't start REPL server"); - } - - this.clientContext = new ClientContextImpl(null, null); - - try { - clientContext.startSession(); - } finally { - clientContext.displayReply("Goodbye from " + languageName + "/REPL"); - } - - } - - public void addCommand(REPLCommand replCommand) { - final String commandName = replCommand.getCommand(); - final String abbreviation = replCommand.getAbbreviation(); - - commandNames.add(commandName); - commandMap.put(commandName, replCommand); - if (abbreviation != null) { - commandMap.put(abbreviation, replCommand); - } - } - - private class ClientContextImpl implements REPLClientContext { - - private final ClientContextImpl predecessor; - private final int level; - - // Information about where the execution is halted - /** The source where execution, if any, is halted; null if none. */ - private Source haltedSource = null; - /** The line number where execution, if any, is halted; 0 if none. */ - private int haltedLineNumber = 0; - /** The stack where execution, if any, is halted; null if none. Evaluated lazily. */ - private List frames = null; - - /** The frame number currently selected by user. */ - private int selectedFrameNumber = 0; - - private String currentPrompt; - - /** - * Create a new context on the occasion of an execution halting. - */ - public ClientContextImpl(ClientContextImpl predecessor, REPLMessage message) { - this.predecessor = predecessor; - this.level = predecessor == null ? 0 : predecessor.level + 1; - - if (message != null) { - try { - this.haltedSource = Source.fromFileName(message.get(REPLMessage.SOURCE_NAME)); - selectedSource = this.haltedSource; - try { - haltedLineNumber = Integer.parseInt(message.get(REPLMessage.LINE_NUMBER)); - } catch (NumberFormatException e) { - haltedLineNumber = 0; - } - } catch (IOException e1) { - this.haltedSource = null; - this.haltedLineNumber = 0; - } - } - updatePrompt(); - } - - private void selectSource(String fileName) { - try { - selectedSource = Source.fromFileName(fileName); - } catch (IOException e1) { - selectedSource = null; - } - updatePrompt(); - } - - private void updatePrompt() { - if (level == 0) { - // 0-level context; no executions halted. - if (selectedSource == null) { - currentPrompt = languageName == null ? "() " : "( " + languageName + " ) "; - } else { - currentPrompt = "(" + selectedSource.getShortName() + ") "; - } - } else if (selectedSource != null && selectedSource != haltedSource) { - // User is focusing somewhere else than the current locn; show no line number. - final StringBuilder sb = new StringBuilder(); - sb.append("(<" + Integer.toString(level) + "> "); - sb.append(selectedSource.getShortName()); - sb.append(") "); - currentPrompt = sb.toString(); - } else { - // Prompt reveals where currently halted. - final StringBuilder sb = new StringBuilder(); - sb.append("(<" + Integer.toString(level) + "> "); - sb.append(haltedSource == null ? "??" : haltedSource.getShortName()); - if (haltedLineNumber > 0) { - sb.append(":" + Integer.toString(haltedLineNumber)); - } - sb.append(") "); - currentPrompt = sb.toString(); - } - - } - - public Source source() { - return haltedSource; - } - - public int lineNumber() { - return haltedLineNumber; - } - - public List frames() { - if (frames == null) { - final REPLMessage request = new REPLMessage(REPLMessage.OP, REPLMessage.BACKTRACE); - final REPLMessage[] replies = sendToServer(request); - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - return null; - } - frames = new ArrayList<>(); - for (REPLMessage reply : replies) { - final int index = reply.getIntValue(REPLMessage.FRAME_NUMBER); - final String locationFilePath = reply.get(REPLMessage.FILE_PATH); - final Integer locationLineNumber = reply.getIntValue(REPLMessage.LINE_NUMBER); - final String locationDescription = reply.get(REPLMessage.SOURCE_LOCATION); - final String name = reply.get(REPLMessage.METHOD_NAME); - final String sourceLineText = reply.get(REPLMessage.SOURCE_LINE_TEXT); - frames.add(new REPLFrameImpl(index, locationFilePath, locationLineNumber, locationDescription, name, sourceLineText)); - } - frames = Collections.unmodifiableList(frames); - } - return frames; - } - - public int level() { - return this.level; - } - - public Source getSelectedSource() { - return selectedSource == null ? haltedSource : selectedSource; - } - - public int getSelectedFrameNumber() { - return selectedFrameNumber; - } - - public String stringQuery(String op) { - assert op != null; - REPLMessage request = null; - switch (op) { - case REPLMessage.TRUFFLE_AST: - request = truffleASTCommand.createRequest(clientContext, NULL_ARGS); - break; - case REPLMessage.TRUFFLE_SUBTREE: - request = truffleSubtreeCommand.createRequest(clientContext, NULL_ARGS); - break; - default: - request = new REPLMessage(); - request.put(REPLMessage.OP, op); - } - if (request == null) { - return null; - } - final REPLMessage[] replies = sendToServer(request); - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - return null; - } - return replies[0].get(REPLMessage.DISPLAY_MSG); - } - - public void selectFrameNumber(int frameNumber) { - this.selectedFrameNumber = frameNumber; - } - - void displayWhere() { - if (level == 0) { - displayFailReply("no active execution"); - return; - } - - Source whereSource = null; - int whereLineNumber = 0; - - if (selectedFrameNumber == 0) { - whereSource = haltedSource; - whereLineNumber = haltedLineNumber; - } else { - final REPLFrame frame = frames().get(selectedFrameNumber); - final String locationFileName = frame.locationFilePath(); - if (locationFileName != null) { - try { - whereSource = Source.fromFileName(locationFileName); - } catch (IOException e) { - } - } - whereLineNumber = frame.locationLineNumber(); - } - if (whereSource == null) { - displayFailReply("Frame " + selectedFrameNumber + ": source unavailable"); - return; - } - final int listSize = listSizeOption.getInt(); - - final int fileLineCount = whereSource.getLineCount(); - final String code = whereSource.getCode(); - - writer.println("Frame " + selectedFrameNumber + ": " + whereSource.getShortName() + "\n"); - final int halfListSize = listSize / 2; - final int startLineNumber = Math.max(1, whereLineNumber - halfListSize); - final int lastLineNumber = Math.min(startLineNumber + listSize - 1, fileLineCount); - for (int line = startLineNumber; line <= lastLineNumber; line++) { - final int offset = whereSource.getLineStartOffset(line); - final String lineText = code.substring(offset, offset + whereSource.getLineLength(line)); - if (line == whereLineNumber) { - writer.format(CODE_LINE_BREAK_FORMAT, line, lineText); - } else { - writer.format(CODE_LINE_FORMAT, line, lineText); - } - } - } - - public void displayStack() { - final List frameList = frames(); - if (frameList == null) { - writer.println(""); - } else { - for (REPLFrame frame : frameList) { - String sourceLineText = frame.sourceLineText(); - if (sourceLineText == null) { - sourceLineText = ""; - } - if (frame.index() == selectedFrameNumber) { - writer.format(STACK_FRAME_SELECTED_FORMAT, frame.index(), frame.locationDescription(), frame.name(), sourceLineText); - } else { - writer.format(STACK_FRAME_FORMAT, frame.index(), frame.locationDescription(), frame.name(), sourceLineText); - } - } - } - } - - public void displayInfo(String message) { - writer.format(INFO_LINE_FORMAT, message); - } - - public void displayReply(String message) { - writer.println(REPLY_PREFIX + message); - } - - public void displayFailReply(String message) { - writer.println(FAIL_PREFIX + message); - } - - public void displayWarnings(String warnings) { - for (String warning : warnings.split("\\n")) { - writer.println(WARNING_PREFIX + warning); - } - } - - public void traceMessage(String message) { - writer.println(TRACE_PREFIX + message); - } - - public void startSession() { - - while (true) { - try { - String[] args; - String line = reader.readLine(currentPrompt).trim(); - if (line.startsWith("eval ")) { - args = new String[]{"eval", line.substring(5)}; - } else { - args = line.split("[ \t]+"); - } - if (args.length == 0) { - break; - } - final String cmd = args[0]; - - if (cmd.isEmpty()) { - continue; - } - - REPLCommand command = commandMap.get(cmd); - while (command instanceof REPLIndirectCommand) { - if (traceMessagesOption.getBool()) { - traceMessage("Executing indirect: " + command.getCommand()); - } - command = ((REPLIndirectCommand) command).getCommand(args); - } - if (command == null) { - clientContext.displayFailReply("Unrecognized command \"" + cmd + "\""); - continue; - } - if (command instanceof REPLLocalCommand) { - if (traceMessagesOption.getBool()) { - traceMessage("Executing local: " + command.getCommand()); - } - ((REPLLocalCommand) command).execute(args); - - } else if (command instanceof REPLRemoteCommand) { - final REPLRemoteCommand remoteCommand = (REPLRemoteCommand) command; - - final REPLMessage request = remoteCommand.createRequest(clientContext, args); - if (request == null) { - continue; - } - - REPLMessage[] replies = sendToServer(request); - - remoteCommand.processReply(clientContext, replies); - } else { - assert false; // Should not happen. - } - - } catch (REPLContinueException ex) { - break; - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - private REPLMessage[] sendToServer(REPLMessage request) { - if (traceMessagesOption.getBool()) { - clientContext.traceMessage("Sever request:"); - request.print(writer, " "); - } - - REPLMessage[] replies = replServer.receive(request); - - assert replies != null && replies.length > 0; - if (traceMessagesOption.getBool()) { - if (replies.length > 1) { - clientContext.traceMessage("Received " + replies.length + " server replies"); - int replyCount = 0; - for (REPLMessage reply : replies) { - clientContext.traceMessage("Server Reply " + replyCount++ + ":"); - reply.print(writer, " "); - } - } else { - clientContext.traceMessage("Received reply:"); - replies[0].print(writer, " "); - } - } - return replies; - } - - private final class REPLFrameImpl implements REPLFrame { - - private final int index; - private final String locationFilePath; - private final Integer locationLineNumber; - private final String locationDescription; - private final String name; - private final String sourceLineText; - - REPLFrameImpl(int index, String locationFilePath, Integer locationLineNumber, String locationDescription, String name, String sourceLineText) { - this.index = index; - this.locationFilePath = locationFilePath; - this.locationLineNumber = locationLineNumber; - this.locationDescription = locationDescription; - this.name = name; - this.sourceLineText = sourceLineText; - } - - public int index() { - return index; - } - - public String locationFilePath() { - return locationFilePath; - } - - public Integer locationLineNumber() { - return locationLineNumber; - } - - public String locationDescription() { - return locationDescription; - } - - public String name() { - return name; - } - - public String sourceLineText() { - return sourceLineText; - } - - } - - } - - // Cheating with synchrony: asynchronous replies should arrive here, but don't. - @Override - public REPLMessage receive(REPLMessage request) { - final String result = request.get("result"); - clientContext.displayReply(result != null ? result : request.toString()); - return null; - } - - /** - * Cheating with synchrony: take a direct call from the server that execution has halted and - * we've entered a nested debugging context. - */ - public void halted(REPLMessage message) { - - // Push a new context for where we've stopped. - clientContext = new ClientContextImpl(clientContext, message); - final String warnings = message.get(REPLMessage.WARNINGS); - if (warnings != null) { - clientContext.displayWarnings(warnings); - } - if (autoWhereOption.getBool()) { - clientContext.displayWhere(); - } - if (autoNodeOption.getBool()) { - final String result = clientContext.stringQuery(REPLMessage.TRUFFLE_NODE); - if (result != null) { - displayTruffleNode(result); - } - } - if (autoASTOption.getBool()) { - final String result = clientContext.stringQuery(REPLMessage.TRUFFLE_AST); - if (result != null) { - displayTruffleAST(result); - } - } - if (autoSubtreeOption.getBool()) { - final String result = clientContext.stringQuery(REPLMessage.TRUFFLE_SUBTREE); - if (result != null) { - displayTruffleSubtree(result); - } - } - - try { - clientContext.startSession(); - } finally { - - // To continue execution, pop the context and return - this.clientContext = clientContext.predecessor; - } - } - - /** - * A command that can be executed without (direct) communication with the server; it may rely on - * some other method that goes to the server for information. - */ - private abstract class REPLLocalCommand extends REPLCommand { - - public REPLLocalCommand(String command, String abbreviation, String description) { - super(command, abbreviation, description); - } - - abstract void execute(String[] args); - } - - /** - * A command that redirects to other commands, based on arguments. - */ - private abstract class REPLIndirectCommand extends REPLCommand { - - public REPLIndirectCommand(String command, String abbreviation, String description) { - super(command, abbreviation, description); - } - - abstract void addCommand(REPLCommand command); - - abstract REPLCommand getCommand(String[] args); - } - - private final REPLCommand backtraceCommand = new REPLLocalCommand("backtrace", "bt", "Display current stack") { - - @Override - void execute(String[] args) { - if (clientContext.level == 0) { - clientContext.displayFailReply("no active execution"); - } else { - clientContext.displayStack(); - } - } - }; - - private final REPLCommand evalCommand = new REPLRemoteCommand("eval", null, "Evaluate a string, in context of the current frame if any") { - - private int evalCounter = 0; - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length > 1) { - final String code = args[1]; - if (!code.isEmpty()) { - // Create a fake entry in the file maps and cache, based on this unique name - final String fakeFileName = ""; - Source.fromNamedText(fakeFileName, code); - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.EVAL); - request.put(REPLMessage.CODE, code); - request.put(REPLMessage.SOURCE_NAME, fakeFileName); - if (clientContext.level > 0) { - // Specify a requested execution context, if one exists; otherwise top level - request.put(REPLMessage.FRAME_NUMBER, Integer.toString(context.getSelectedFrameNumber())); - } - return request; - } - } - return null; - } - }; - - private final REPLCommand fileCommand = new REPLRemoteCommand("file", null, "Set/display current file for viewing") { - - final String[] help = {"file: display current file path", "file : Set file to be current file for viewing"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - if (args.length == 1) { - final Source source = clientContext.getSelectedSource(); - if (source == null) { - clientContext.displayFailReply("no file currently selected"); - } else { - clientContext.displayReply(source.getPath()); - } - return null; - } - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.FILE); - request.put(REPLMessage.SOURCE_NAME, args[1]); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - REPLMessage firstReply = replies[0]; - - if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - final String result = firstReply.get(REPLMessage.DISPLAY_MSG); - clientContext.displayFailReply(result != null ? result : firstReply.toString()); - return; - } - final String fileName = firstReply.get(REPLMessage.SOURCE_NAME); - final String path = firstReply.get(REPLMessage.FILE_PATH); - clientContext.selectSource(path == null ? fileName : path); - clientContext.displayReply(clientContext.getSelectedSource().getPath()); - - for (int i = 1; i < replies.length; i++) { - REPLMessage reply = replies[i]; - final String result = reply.get(REPLMessage.DISPLAY_MSG); - clientContext.displayInfo(result != null ? result : reply.toString()); - } - } - - }; - - private final REPLCommand helpCommand = new REPLLocalCommand("help", null, "Describe commands") { - - final String[] help = {"help: list available commands", "help : additional information about "}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public void execute(String[] args) { - - if (args.length == 1) { - clientContext.displayReply("Available commands:"); - for (String commandName : commandNames) { - final REPLCommand command = commandMap.get(commandName); - if (command == null) { - clientContext.displayInfo(commandName + ": Error, no implementation for command"); - } else { - final String abbrev = command.getAbbreviation(); - if (abbrev == null) { - clientContext.displayInfo(commandName + ": " + command.getDescription()); - } else { - clientContext.displayInfo(commandName + "(" + abbrev + "): " + command.getDescription()); - } - } - } - } else { - final String cmdName = args[1]; - final REPLCommand cmd = commandMap.get(cmdName); - if (cmd == null) { - clientContext.displayReply("command \"" + cmdName + "\" not recognized"); - } else { - final String[] helpLines = cmd.getHelp(); - if (helpLines == null) { - clientContext.displayReply("\"" + cmdName + "\":"); - } else if (helpLines.length == 1) { - clientContext.displayInfo(helpLines[0]); - } else { - clientContext.displayReply("\"" + cmdName + "\":"); - for (String line : helpLines) { - clientContext.displayInfo(line); - } - } - } - } - } - }; - - private final REPLIndirectCommand infoCommand = new REPLIndirectCommand(REPLMessage.INFO, null, "Additional information on topics") { - - // "Info" commands - private final Map infoCommandMap = new HashMap<>(); - private final Collection infoCommandNames = new TreeSet<>(); - - @Override - public String[] getHelp() { - final ArrayList lines = new ArrayList<>(); - for (String infoCommandName : infoCommandNames) { - final REPLCommand cmd = infoCommandMap.get(infoCommandName); - if (cmd == null) { - lines.add("\"" + REPLMessage.INFO + " " + infoCommandName + "\" not implemented"); - } else { - lines.add("\"" + REPLMessage.INFO + " " + infoCommandName + "\": " + cmd.getDescription()); - } - } - return lines.toArray(new String[0]); - } - - @Override - void addCommand(REPLCommand replCommand) { - final String commandName = replCommand.getCommand(); - final String abbreviation = replCommand.getAbbreviation(); - - infoCommandNames.add(commandName); - infoCommandMap.put(commandName, replCommand); - if (abbreviation != null) { - infoCommandMap.put(abbreviation, replCommand); - } - } - - @Override - REPLCommand getCommand(String[] args) { - if (args.length == 1) { - clientContext.displayFailReply("info topic not specified; try \"help info\""); - return null; - } - final String topic = args[1]; - REPLCommand command = infoCommandMap.get(topic); - if (command == null) { - clientContext.displayFailReply("topic \"" + topic + "\" not recognized"); - return null; - } - - return command; - } - - }; - - private final REPLCommand infoBreakCommand = new REPLRemoteCommand("breakpoint", "break", "info about breakpoints") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.BREAKPOINT_INFO); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - clientContext.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); - } else { - Arrays.sort(replies, new Comparator() { - - public int compare(REPLMessage o1, REPLMessage o2) { - try { - final int n1 = Integer.parseInt(o1.get(REPLMessage.BREAKPOINT_ID)); - final int n2 = Integer.parseInt(o2.get(REPLMessage.BREAKPOINT_ID)); - return Integer.compare(n1, n2); - } catch (Exception ex) { - } - return 0; - } - - }); - clientContext.displayReply("Breakpoints set:"); - for (REPLMessage message : replies) { - final StringBuilder sb = new StringBuilder(); - - sb.append(Integer.parseInt(message.get(REPLMessage.BREAKPOINT_ID)) + ": "); - sb.append("@" + message.get(REPLMessage.INFO_VALUE)); - sb.append(" (state=" + message.get(REPLMessage.BREAKPOINT_STATE)); - if (verboseBreakpointInfoOption.getBool()) { - sb.append(", group=" + Integer.parseInt(message.get(REPLMessage.BREAKPOINT_GROUP_ID))); - sb.append(", hits=" + Integer.parseInt(message.get(REPLMessage.BREAKPOINT_HIT_COUNT))); - sb.append(", ignore=" + Integer.parseInt(message.get(REPLMessage.BREAKPOINT_IGNORE_COUNT))); - } - final String condition = message.get(REPLMessage.BREAKPOINT_CONDITION); - if (condition != null) { - sb.append(", condition=\"" + condition + "\""); - } - sb.append(")"); - clientContext.displayInfo(sb.toString()); - } - } - } - }; - - private final REPLCommand infoLanguageCommand = new REPLRemoteCommand("language", "lang", "language and implementation details") { - - final String[] help = {"info language: list details about the language implementation"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.INFO); - request.put(REPLMessage.TOPIC, REPLMessage.LANGUAGE); - return request; - } - - @Override - void processReply(REPLClientContext context, REPLMessage[] replies) { - if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { - clientContext.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); - } else { - clientContext.displayReply("Language info:"); - for (REPLMessage message : replies) { - final StringBuilder sb = new StringBuilder(); - sb.append(message.get(REPLMessage.INFO_KEY)); - sb.append(": "); - sb.append(message.get(REPLMessage.INFO_VALUE)); - clientContext.displayInfo(sb.toString()); - } - } - } - }; - - private final REPLCommand infoSetCommand = new REPLLocalCommand("set", null, "info about settings") { - - final String[] help = {"info sets: list local options that can be set"}; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public void execute(String[] args) { - - clientContext.displayReply("Settable options:"); - - for (String optionName : optionNames) { - final LocalOption localOption = localOptions.get(optionName); - if (localOption == null) { - clientContext.displayInfo(localOption + ": Error, no implementation for option"); - } else { - clientContext.displayInfo(optionName + "=" + localOption.getValue() + ": " + localOption.getDescription()); - } - } - } - }; - - private final REPLCommand listCommand = new REPLLocalCommand("list", null, "Display selected source file") { - - final String[] help = {"list: list lines of selected file (see option \"listsize\")", "list all: list all lines", "list : list lines centered around line "}; - - private Source lastListedSource = null; - - private int nextLineToList = 1; - - @Override - public String[] getHelp() { - return help; - } - - @Override - public void execute(String[] args) { - final Source source = clientContext.getSelectedSource(); - if (source == null) { - clientContext.displayFailReply("No selected file"); - reset(); - return; - } - final int listSize = listSizeOption.getInt(); - - if (args.length == 1) { - if (!source.equals(lastListedSource)) { - reset(); - } else if (nextLineToList > source.getLineCount()) { - reset(); - } - final int lastListedLine = printLines(source, nextLineToList, listSize); - lastListedSource = source; - nextLineToList = lastListedLine > source.getLineCount() ? 1 : lastListedLine + 1; - } else if (args.length == 2) { - reset(); - if (args[1].equals("all")) { - printLines(source, 1, source.getLineCount()); - } else { - try { - final int line = Integer.parseInt(args[1]); - final int halfListSize = listSize / 2; - final int start = Math.max(1, line - halfListSize); - final int count = Math.min(source.getLineCount() + 1 - start, listSize); - printLines(source, start, count); - } catch (NumberFormatException e) { - clientContext.displayFailReply("\"" + args[1] + "\" not recognized"); - } - - } - } - } - - private int printLines(Source printSource, int start, int listSize) { - - clientContext.displayReply(printSource.getShortName() + ":"); - final int lastLineNumber = Math.min(start + listSize - 1, printSource.getLineCount()); - for (int line = start; line <= lastLineNumber; line++) { - writer.format(CODE_LINE_FORMAT, line, printSource.getCode(line)); - } - return lastLineNumber; - } - - /** - * Forget where we were in a sequence of list commands with no arguments - */ - private void reset() { - lastListedSource = clientContext.getSelectedSource(); - nextLineToList = 1; - } - }; - - private final REPLCommand quitCommand = new REPLRemoteCommand("quit", "q", "Quit execution and REPL") { - - @Override - public REPLMessage createRequest(REPLClientContext context, String[] args) { - final REPLMessage request = new REPLMessage(); - request.put(REPLMessage.OP, REPLMessage.QUIT); - return request; - } - - }; - - private final REPLCommand setCommand = new REPLLocalCommand("set", null, "set