# HG changeset patch
# User Christian Humer
# Date 1389117184 -3600
# Node ID 856c2c294f84436a645606d7035be3c072ef6ddc
# Parent 5a0c694ef735053dc64ecbbe6bf04f6766b3ac87# Parent 56452e07874f936e2e4292e63d3c5cafd81542c1
Merge.
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BoxedString.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BoxedString.java Tue Jan 07 18:53:04 2014 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Jan 07 18:53:04 2014 +0100
@@ -38,8 +38,6 @@
import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve1Factory;
import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve2Factory;
import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve3Factory;
-import com.oracle.truffle.api.dsl.test.NodeContainerTest.Str;
-import com.oracle.truffle.api.dsl.test.NodeContainerTest.StrBase;
import com.oracle.truffle.api.dsl.test.TypeSystemTest.Abstract;
import com.oracle.truffle.api.dsl.test.TypeSystemTest.BExtendsAbstract;
import com.oracle.truffle.api.dsl.test.TypeSystemTest.CExtendsAbstract;
@@ -124,18 +122,18 @@
public void testGuardWithBaseClass() {
TestRootNode> root = createRoot(GuardWithBaseClassFactory.getInstance());
- assertEquals(42, executeWith(root, new Str("42")));
+ assertEquals(42, executeWith(root, new BExtendsAbstract()));
}
@NodeChild("expression")
public abstract static class GuardWithBaseClass extends ValueNode {
- boolean baseGuard(StrBase base) {
+ boolean baseGuard(Abstract base) {
return true;
}
@Specialization(guards = "baseGuard")
- int doSpecialized(Str value0) {
+ int doSpecialized(BExtendsAbstract value0) {
return 42;
}
}
@@ -227,7 +225,7 @@
@Test
public void testGuardResolve2() {
TestRootNode> root = createRoot(TestGuardResolve2Factory.getInstance());
- assertEquals(42, executeWith(root, new Str("")));
+ assertEquals(42, executeWith(root, new BExtendsAbstract()));
}
@NodeChild("expression")
@@ -237,12 +235,12 @@
return false;
}
- boolean guard(StrBase primitive) {
+ boolean guard(Abstract primitive) {
return true;
}
@Specialization(guards = "guard")
- int doSpecialized(Str value0) {
+ int doSpecialized(BExtendsAbstract value0) {
return 42;
}
}
@@ -251,7 +249,7 @@
public void testGuardResolve3() {
TestRootNode> root = createRoot(TestGuardResolve3Factory.getInstance());
- assertEquals(42, executeWith(root, new Str("")));
+ assertEquals(42, executeWith(root, new BExtendsAbstract()));
}
@NodeChild("expression")
@@ -261,16 +259,16 @@
return false;
}
- boolean guard(StrBase primitive) {
+ boolean guard(Abstract primitive) {
return false;
}
- boolean guard(Str primitive) {
+ boolean guard(BExtendsAbstract primitive) {
return true;
}
@Specialization(guards = "guard")
- int doSpecialized(Str value0) {
+ int doSpecialized(BExtendsAbstract value0) {
return 42;
}
}
@@ -278,12 +276,12 @@
@NodeChild("expression")
public abstract static class TestGuardResolve4 extends ValueNode {
- boolean guard(StrBase primitive) {
+ boolean guard(Abstract primitive) {
return false;
}
@Specialization(guards = "guard")
- int doSpecialized(Str value0) {
+ int doSpecialized(BExtendsAbstract value0) {
return 42;
}
}
diff -r 56452e07874f -r 856c2c294f84 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 Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,14 +28,13 @@
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.NodeContainerTest.Str;
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, boolean.class, String.class, Str.class})
+ @TypeSystem({int.class, boolean.class, String.class})
static class ImplicitCast0Types {
@ImplicitCast
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java Tue Jan 07 14:41:52 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +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.NodeContainerTestFactory.StrFactory.StrAccessContextFactory;
-import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrConcatFactory;
-import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrLengthFactory;
-import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrSubstrFactory;
-import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
-
-public class NodeContainerTest {
-
- @Test
- public void testConcat() {
- TestRootNode node = createRoot(StrConcatFactory.getInstance(), new Context());
- Str str1 = new Str("42");
- Str str2 = new Str(" is the number.");
- assertEquals(str1.concat(str2), executeWith(node, str1, str2));
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testConcatUnsupported() {
- TestRootNode node = createRoot(StrConcatFactory.getInstance(), new Context());
- executeWith(node, 42, new Str(" is the number."));
- }
-
- @Test
- public void testSubstrSpecialized() {
- TestRootNode node = createRoot(StrSubstrFactory.getInstance(), new Context());
- Str str = new Str("test 42");
-
- assertEquals(str.substr(5, 7), executeWith(node, str, 5, 7));
- }
-
- @Test
- public void testSubstrGeneric() {
- TestRootNode node = createRoot(StrSubstrFactory.getInstance(), new Context());
- Str str = new Str("test 42");
-
- assertEquals(Str.substr(str, "5", "7"), executeWith(node, str, "5", "7"));
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testSubstrUnsupported() {
- TestRootNode node = createRoot(StrSubstrFactory.getInstance(), new Context());
- executeWith(node, new Object(), "5", "7");
- }
-
- @Test
- public void testLength() {
- TestRootNode node = createRoot(StrLengthFactory.getInstance(), new Context());
- Str testStr = new Str("test 42");
- assertEquals(testStr.length(), executeWith(node, testStr));
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testLengthUnsupported() {
- TestRootNode node = createRoot(StrLengthFactory.getInstance(), new Context());
- executeWith(node, new Object());
- }
-
- @Test
- public void testAccessContext() {
- Context context = new Context();
- TestRootNode node = createRoot(StrAccessContextFactory.getInstance(), context);
- // accessible by node
- assertSame(context, node.getNode().getContext());
- // accessible by execution
- assertSame(context, executeWith(node));
- }
-
- static class StrBase {
-
- }
-
- @NodeContainer(BuiltinNode.class)
- static class Str extends StrBase {
-
- private final String internal;
-
- public Str(String internal) {
- this.internal = internal;
- }
-
- @Specialization
- Str concat(Str s1) {
- return new Str(internal + s1.internal);
- }
-
- @Specialization
- Str substr(int beginIndex, int endIndex) {
- return new Str(internal.substring(beginIndex, endIndex));
- }
-
- @Generic
- static Str substr(Object thisValue, Object beginIndex, Object endIndex) {
- if (!(thisValue instanceof Str)) {
- throw new UnsupportedOperationException();
- }
- return ((Str) thisValue).substr(convertInt(beginIndex), convertInt(endIndex));
- }
-
- @Specialization
- int length() {
- return internal.length();
- }
-
- @Specialization
- static Object accessContext(Context context) {
- return context;
- }
-
- static int convertInt(Object value) {
- if (value instanceof Number) {
- return ((Number) value).intValue();
- } else if (value instanceof String) {
- return Integer.parseInt((String) value);
- }
- throw new RuntimeException("Invalid datatype");
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Str) {
- return internal.equals(((Str) obj).internal);
- }
- return super.equals(obj);
- }
-
- @Override
- public String toString() {
- return internal;
- }
-
- @Override
- public int hashCode() {
- return internal.hashCode();
- }
- }
-
- @NodeChild(value = "children", type = ValueNode[].class)
- @NodeField(name = "context", type = Context.class)
- abstract static class BuiltinNode extends ValueNode {
-
- public abstract Context getContext();
- }
-
- static class Context {
-
- }
-
-}
diff -r 56452e07874f -r 856c2c294f84 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 Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,8 +28,13 @@
import org.junit.*;
import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.*;
-import com.oracle.truffle.api.dsl.test.NodeFieldTestFactory.TestContainerFactory.TestContainerContainerFieldFactory;
+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 {
@@ -125,7 +130,7 @@
@Test
public void testStringContainer() {
- assertEquals(42, createCallTarget(TestContainerContainerFieldFactory.create(42, "42")).call());
+ assertEquals(42, createCallTarget(TestContainerFactory.create("42")).call());
}
@NodeField(name = "field", type = int.class)
@@ -135,13 +140,12 @@
}
- @NodeContainer(IntContainerNode.class)
@NodeField(name = "anotherField", type = String.class)
- abstract static class TestContainer {
+ abstract static class TestContainer extends ValueNode {
@Specialization
- static int containerField(int field, String anotherField) {
- return anotherField.equals("42") ? field : -1;
+ int containerField(String field) {
+ return field.equals("42") ? 42 : -1;
}
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java Tue Jan 07 18:53:04 2014 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import 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.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.TestArguments;
+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 TestArguments(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 TestArguments(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 TestArguments(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 TestArguments(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;
+ }
+
+ }
+
+ @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 TestArguments(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 TestArguments(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;
+ }
+
+ }
+
+}
diff -r 56452e07874f -r 856c2c294f84 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 Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,7 +28,6 @@
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.dsl.test.NodeContainerTest.BuiltinNode;
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.TestArguments;
@@ -52,7 +51,7 @@
ArgumentNode[] argumentNodes = arguments(factory.getExecutionSignature().size());
List
*
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeContainer.java
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeContainer.java Tue Jan 07 14:41:52 2014 +0100
+++ /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.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * A node container can be used to enable Truffle-DSL in classes which do not extend {@link Node}.
- * Compared to normal {@link Node} implementation the nodes are not identified by a class but by
- * their method name. There are cases were method signatures are matching exactly but should be in
- * the same {@link Node}. In this case use {@link NodeId} to disambiguate such cases.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface NodeContainer {
-
- /** The node class to use as base class for {@link Node} definitions grouped by method names. */
- Class extends Node> value();
-
-}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeId.java
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeId.java Tue Jan 07 14:41:52 2014 +0100
+++ /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, ElementType.TYPE})
-public @interface NodeId {
-
- String value();
-
-}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/SpecializationListener.java
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/SpecializationListener.java Tue Jan 07 14:41:52 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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 SpecializationListener {
-}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -46,17 +46,21 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
List childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
- TypeMirror baseType = getContext().getTruffleTypes().getNode();
+ NodeChildData foundChild = null;
for (String childName : childNames) {
- NodeChildData child = getNode().findChild(childName);
- if (child != null) {
- baseType = child.getOriginalType();
+ foundChild = getNode().findChild(childName);
+ if (foundChild != null) {
break;
}
}
+ TypeMirror baseType = getContext().getTruffleTypes().getNode();
+ if (foundChild != null) {
+ baseType = foundChild.getOriginalType();
+ }
+
MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType));
addDefaultFieldMethodSpec(spec);
- spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true);
+ spec.addRequired(new ParameterSpec("castedChild", baseType));
return spec;
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -29,7 +29,6 @@
import javax.lang.model.type.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
import com.oracle.truffle.dsl.processor.template.*;
import com.oracle.truffle.dsl.processor.typesystem.*;
@@ -52,13 +51,11 @@
for (ParameterSpec originalSpec : requiredSpecs) {
spec.addRequired(new ParameterSpec(originalSpec, allowedTypes));
}
-
- spec.setVariableRequiredArguments(true);
- ParameterSpec other = new ParameterSpec("other", allowedTypes);
- other.setCardinality(Cardinality.MANY);
- other.setSignature(true);
- other.setIndexed(true);
- spec.addRequired(other);
+ spec.setIgnoreAdditionalSpecifications(true);
+ spec.setIgnoreAdditionalParameters(true);
+ spec.setVariableRequiredParameters(true);
+ // varargs
+ spec.addRequired(new ParameterSpec("other", allowedTypes));
return spec;
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -30,6 +30,7 @@
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.SpecializationData.SpecializationKind;
import com.oracle.truffle.dsl.processor.template.*;
public class GenericParser extends NodeMethodParser {
@@ -44,26 +45,20 @@
}
@Override
- protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
- List execTypes = nodeData.findGenericExecutableTypes(getContext(), evaluatedCount);
+ protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) {
+ List execTypes = execution.getChild().getNodeData().findGenericExecutableTypes(getContext(), execution.getChild().getExecuteWith().size());
List types = new ArrayList<>();
for (ExecutableTypeData type : execTypes) {
types.add(type.getType().getPrimitiveType());
}
- ParameterSpec spec = new ParameterSpec(valueName, types);
- spec.setSignature(true);
+ ParameterSpec spec = new ParameterSpec(execution.getName(), types);
+ spec.setExecution(execution);
return spec;
}
@Override
- protected ParameterSpec createReturnParameterSpec() {
- return super.createValueParameterSpec("returnValue", getNode(), 0);
- }
-
- @Override
public SpecializationData create(TemplateMethod method, boolean invalid) {
- SpecializationData data = new SpecializationData(method, true, false, false);
- return data;
+ return new SpecializationData(getNode(), method, SpecializationKind.GENERIC);
}
@Override
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Tue Jan 07 18:53:04 2014 +0100
@@ -45,29 +45,20 @@
}
}
- public enum ExecutionKind {
- DEFAULT, SHORT_CIRCUIT
- }
-
- private final NodeData parent;
+ private NodeData parentNode;
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 final ExecutionKind executionKind;
private List executeWith = Collections.emptyList();
- private NodeData nodeData;
+ private NodeData childNode;
- public NodeChildData(NodeData parent, Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement,
- Cardinality cardinality, ExecutionKind executionKind) {
- this.parent = parent;
+ 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;
@@ -75,7 +66,10 @@
this.originalType = originalNodeType;
this.accessElement = accessElement;
this.cardinality = cardinality;
- this.executionKind = executionKind;
+ }
+
+ void setParentNode(NodeData parentNode) {
+ this.parentNode = parentNode;
}
public List getExecuteWith() {
@@ -87,23 +81,17 @@
}
public boolean needsImplicitCast(ProcessorContext context) {
- if (!parent.needsRewrites(context)) {
+ if (!parentNode.needsRewrites(context)) {
return false;
}
boolean used = false;
- SpecializationData generic = parent.getGenericSpecialization();
- for (ActualParameter param : generic.getParameters()) {
- if (!param.getSpecification().isSignature()) {
- continue;
- }
- NodeChildData child = parent.findChild(param.getSpecification().getName());
- if (child == this) {
+ for (NodeExecutionData execution : parentNode.getChildExecutions()) {
+ if (execution.getChild() == this) {
used = true;
break;
}
}
-
if (!used) {
return false;
}
@@ -112,7 +100,7 @@
}
public ExecutableTypeData findExecutableType(ProcessorContext context, TypeData targetType) {
- ExecutableTypeData executableType = nodeData.findExecutableType(targetType, getExecuteWith().size());
+ ExecutableTypeData executableType = childNode.findExecutableType(targetType, getExecuteWith().size());
if (executableType == null) {
executableType = findAnyGenericExecutableType(context);
}
@@ -120,15 +108,15 @@
}
public List findGenericExecutableTypes(ProcessorContext context) {
- return nodeData.findGenericExecutableTypes(context, getExecuteWith().size());
+ return childNode.findGenericExecutableTypes(context, getExecuteWith().size());
}
public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) {
- return nodeData.findAnyGenericExecutableType(context, getExecuteWith().size());
+ return childNode.findAnyGenericExecutableType(context, getExecuteWith().size());
}
public List findExecutableTypes() {
- return nodeData.getExecutableTypes(getExecuteWith().size());
+ return childNode.getExecutableTypes(getExecuteWith().size());
}
public TypeMirror getOriginalType() {
@@ -145,12 +133,8 @@
return sourceAnnotationMirror;
}
- public boolean isShortCircuit() {
- return executionKind == ExecutionKind.SHORT_CIRCUIT;
- }
-
void setNode(NodeData nodeData) {
- this.nodeData = nodeData;
+ this.childNode = nodeData;
if (nodeData != null) {
getMessages().addAll(nodeData.collectMessages());
}
@@ -168,12 +152,8 @@
return cardinality;
}
- public ExecutionKind getExecutionKind() {
- return executionKind;
- }
-
public NodeData getNodeData() {
- return nodeData;
+ return childNode;
}
public String getName() {
@@ -182,7 +162,7 @@
@Override
public String toString() {
- return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", execution=" + executionKind + ", node=" + getNodeData() + "]";
+ return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", node=" + getNodeData() + "]";
}
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Jan 07 18:53:04 2014 +0100
@@ -37,7 +37,6 @@
import com.oracle.truffle.dsl.processor.*;
import com.oracle.truffle.dsl.processor.ast.*;
import com.oracle.truffle.dsl.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind;
import com.oracle.truffle.dsl.processor.node.SpecializationGroup.TypeGuard;
import com.oracle.truffle.dsl.processor.template.*;
import com.oracle.truffle.dsl.processor.typesystem.*;
@@ -48,6 +47,7 @@
private static final String EXECUTE_GENERIC_NAME = "executeGeneric0";
private static final String EXECUTE_SPECIALIZE_NAME = "executeAndSpecialize0";
+ private static final String EXECUTE_POLYMORPHIC_NAME = "executePolymorphic0";
private static final String UPDATE_TYPES_NAME = "updateTypes";
@@ -71,16 +71,8 @@
return name;
}
- private static String nodePolymorphicClassName(NodeData node, SpecializationData specialization) {
- String nodeid = resolveNodeId(node);
-
- String name = Utils.firstLetterUpperCase(nodeid);
- if (specialization == node.getGenericPolymorphicSpecialization()) {
- name += "PolymorphicNode";
- } else {
- name += "Polymorphic" + polymorphicIndex(node, specialization) + "Node";
- }
- return name;
+ private static String nodePolymorphicClassName(NodeData node) {
+ return Utils.firstLetterUpperCase(resolveNodeId(node)) + "PolymorphicNode";
}
private static String resolveNodeId(NodeData node) {
@@ -111,30 +103,6 @@
return valueName(parameter) + "Cast";
}
- private static String executeCachedName(SpecializationData polymorphic) {
- NodeData node = polymorphic.getNode();
- boolean generic = polymorphic == node.getGenericPolymorphicSpecialization();
-
- if (generic) {
- return "executeCachedGeneric0";
- } else {
- return "executeCached" + polymorphicIndex(node, polymorphic);
- }
- }
-
- private static int polymorphicIndex(NodeData node, SpecializationData polymorphic) {
- int index = 0;
- for (SpecializationData specialization : node.getPolymorphicSpecializations()) {
- if (specialization == polymorphic) {
- break;
- }
- if (specialization != node.getGenericPolymorphicSpecialization()) {
- index++;
- }
- }
- return index;
- }
-
private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) {
if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
@@ -440,11 +408,9 @@
getElement().getEnclosedElements().clear();
Map> childTypes = new LinkedHashMap<>();
- if (node.getDeclaredNodes() != null && !node.getDeclaredNodes().isEmpty()) {
- for (NodeData nodeChild : node.getDeclaredNodes()) {
- NodeCodeGenerator generator = new NodeCodeGenerator(getContext());
- childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements());
- }
+ for (NodeData nodeChild : node.getEnclosingNodes()) {
+ NodeCodeGenerator generator = new NodeCodeGenerator(getContext());
+ childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements());
}
if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) {
@@ -526,15 +492,18 @@
createFactoryMethods(node, clazz, createVisibility);
- if (node.isPolymorphic()) {
- PolymorphicNodeFactory generic = new PolymorphicNodeFactory(getContext(), generatedNode);
- add(generic, node.getGenericPolymorphicSpecialization());
- polymorphicNode = generic.getElement();
- }
for (SpecializationData specialization : node.getSpecializations()) {
if (!specialization.isReachable()) {
continue;
}
+
+ if (specialization.isPolymorphic() && node.isPolymorphic()) {
+ PolymorphicNodeFactory polymorphicFactory = new PolymorphicNodeFactory(getContext(), generatedNode);
+ add(polymorphicFactory, specialization);
+ polymorphicNode = polymorphicFactory.getElement();
+ continue;
+ }
+
add(new SpecializedNodeFactory(context, generatedNode), specialization);
}
@@ -573,7 +542,7 @@
}
List children = node.getNodeDeclaringChildren();
- if (node.getParent() == null && children.size() > 0) {
+ if (node.getDeclaringNode() == null && children.size() > 0) {
clazz.add(createGetFactories(node));
}
@@ -632,21 +601,9 @@
List signatureTypes = new ArrayList<>();
assert !node.getSpecializations().isEmpty();
SpecializationData data = node.getSpecializations().get(0);
- for (ActualParameter parameter : data.getParameters()) {
- ParameterSpec spec = parameter.getSpecification();
- NodeChildData field = node.findChild(spec.getName());
- if (field == null) {
- continue;
- }
-
- TypeMirror type;
- if (field.getCardinality() == Cardinality.MANY && field.getNodeType().getKind() == TypeKind.ARRAY) {
- type = ((ArrayType) field.getNodeType()).getComponentType();
- } else {
- type = field.getNodeType();
- }
-
- signatureTypes.add(type);
+
+ for (ActualParameter parameter : data.getSignatureParameters()) {
+ signatureTypes.add(parameter.getSpecification().getExecution().getNodeType());
}
builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
@@ -768,7 +725,7 @@
}
private String instanceVarName(NodeData node) {
- if (node.getParent() != null) {
+ if (node.getDeclaringNode() != null) {
return Utils.firstLetterLowerCase(factoryClassName(node)) + "Instance";
} else {
return "instance";
@@ -821,9 +778,9 @@
builder.startGroup();
NodeData childNode = child;
List factories = new ArrayList<>();
- while (childNode.getParent() != null) {
+ while (childNode.getDeclaringNode() != null) {
factories.add(childNode);
- childNode = childNode.getParent();
+ childNode = childNode.getDeclaringNode();
}
Collections.reverse(factories);
for (NodeData nodeData : factories) {
@@ -963,7 +920,7 @@
builder.statement("this.next0 = adoptChild(next0)");
clazz.add(setter);
- CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getGenericPolymorphicSpecialization());
+ CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization());
clazz.add(genericCachedExecute);
getElement().add(createUpdateTypes(clazz.asType()));
@@ -1014,16 +971,13 @@
CodeTreeBuilder oldBuilder = builder.create();
CodeTreeBuilder resetBuilder = builder.create();
- for (ActualParameter param : getModel().getParameters()) {
- if (!param.getSpecification().isSignature()) {
- continue;
- }
- NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
+ for (ActualParameter param : getModel().getSignatureParameters()) {
+ NodeChildData child = param.getSpecification().getExecution().getChild();
CodeTreeBuilder access = builder.create();
access.string("this.").string(child.getName());
if (child.getCardinality().isMany()) {
- access.string("[").string(String.valueOf(param.getSpecificationIndex())).string("]");
+ access.string("[").string(String.valueOf(param.getSpecificationVarArgsIndex())).string("]");
}
String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
@@ -1117,11 +1071,7 @@
builder.startStatement().startCall("builder", "append").doubleQuote(" (").end().end();
String sep = null;
- for (ActualParameter parameter : node.getGenericSpecialization().getParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- continue;
- }
-
+ for (ActualParameter parameter : node.getGenericSpecialization().getSignatureParameters()) {
builder.startStatement();
builder.string("builder");
if (sep != null) {
@@ -1164,8 +1114,7 @@
}
private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) {
- String name = executeCachedName(polymorph);
- CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), name);
+ CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_POLYMORPHIC_NAME);
addInternalValueParameters(cachedExecute, polymorph, true, true);
ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0);
@@ -1210,15 +1159,6 @@
}
}
- for (VariableElement var : type.getFields()) {
- NodeChildData child = node.findChild(var.getSimpleName().toString());
- if (child != null) {
- method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName()));
- } else {
- method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString()));
- }
- }
-
if (superConstructor != null) {
builder.startStatement().startSuperCall();
for (VariableElement param : superConstructor.getParameters()) {
@@ -1228,11 +1168,18 @@
}
for (VariableElement var : type.getFields()) {
+ NodeExecutionData execution = node.findExecution(var.getSimpleName().toString());
+ NodeChildData child = execution != null ? execution.getChild() : null;
+
+ if (execution != null) {
+ method.getParameters().add(new CodeVariableElement(execution.getNodeType(), execution.getName()));
+ } else {
+ method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString()));
+ }
+
builder.startStatement();
String fieldName = var.getSimpleName().toString();
- NodeChildData child = node.findChild(fieldName);
-
CodeTree init = createStaticCast(builder, child, fieldName);
init = createAdoptChild(builder, var.asType(), init);
@@ -1327,8 +1274,6 @@
builder.startStaticCall(getContext().getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end();
builder.end();
- emitSpecializationListeners(builder, node);
-
String currentNode = "this";
for (SpecializationData specialization : node.getSpecializations()) {
if (!specialization.getExceptions().isEmpty()) {
@@ -1352,7 +1297,7 @@
boolean firstUnreachable = true;
for (SpecializationData current : node.getSpecializations()) {
- if (current.isUninitialized() || current.isReachable()) {
+ if (current.isReachable()) {
continue;
}
if (firstUnreachable) {
@@ -1369,7 +1314,7 @@
List specializations = node.getSpecializations();
List filteredSpecializations = new ArrayList<>();
for (SpecializationData current : specializations) {
- if (current.isUninitialized() || !current.isReachable()) {
+ if (current.isUninitialized() || current.isPolymorphic() || !current.isReachable()) {
continue;
}
filteredSpecializations.add(current);
@@ -1402,7 +1347,7 @@
private void emitUnreachableSpecializations(final CodeTreeBuilder builder, NodeData node) {
for (SpecializationData current : node.getSpecializations()) {
- if (current.isUninitialized() || current.isReachable()) {
+ if (current.isReachable()) {
continue;
}
builder.string("// unreachable ").string(current.getId()).newLine();
@@ -1520,19 +1465,15 @@
}
}
- NodeChildData child = node.findChild(valueParam.getSpecification().getName());
- if (child == null) {
- throw new IllegalStateException();
- }
-
- CodeTree implicitGuard = createTypeGuard(guardsBuilder, child, valueParam, typeGuard.getType(), typedCasts);
+ NodeExecutionData execution = valueParam.getSpecification().getExecution();
+ CodeTree implicitGuard = createTypeGuard(guardsBuilder, execution, valueParam, typeGuard.getType(), typedCasts);
if (implicitGuard != null) {
guardsBuilder.string(guardsAnd);
guardsBuilder.tree(implicitGuard);
guardsAnd = " && ";
}
- CodeTree cast = createCast(castBuilder, child, valueParam, typeGuard.getType(), checkMinimumState, typedCasts);
+ CodeTree cast = createCast(castBuilder, execution, valueParam, typeGuard.getType(), checkMinimumState, typedCasts);
if (cast != null) {
castBuilder.tree(cast);
}
@@ -1604,8 +1545,8 @@
return false;
}
- private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType, boolean typedCasts) {
- NodeData node = field.getNodeData();
+ private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, ActualParameter source, TypeData targetType, boolean typedCasts) {
+ NodeData node = execution.getChild().getNodeData();
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
@@ -1617,7 +1558,7 @@
builder.startGroup();
- if (field.isShortCircuit()) {
+ if (execution.isShortCircuit()) {
ActualParameter shortCircuit = source.getPreviousParameter();
assert shortCircuit != null;
builder.string("(");
@@ -1644,7 +1585,7 @@
}
builder.end().end(); // call
- if (field.isShortCircuit()) {
+ if (execution.isShortCircuit()) {
builder.string(")");
}
@@ -1654,8 +1595,8 @@
}
// TODO merge redundancies with #createTypeGuard
- private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType, boolean checkMinimumState, boolean typedCasts) {
- NodeData node = field.getNodeData();
+ private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, ActualParameter source, TypeData targetType, boolean checkMinimumState, boolean typedCasts) {
+ NodeData node = execution.getChild().getNodeData();
TypeData sourceType = source.getTypeSystemType();
if (!sourceType.needsCastTo(getContext(), targetType)) {
@@ -1663,7 +1604,7 @@
}
CodeTree condition = null;
- if (field.isShortCircuit()) {
+ if (execution.isShortCircuit()) {
ActualParameter shortCircuit = source.getPreviousParameter();
assert shortCircuit != null;
condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
@@ -1777,7 +1718,7 @@
}
builder.end();
builder.startDoWhile();
- builder.string("!").startParantheses().instanceOf("root", nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization())).end();
+ builder.string("!").startParantheses().instanceOf("root", nodePolymorphicClassName(node)).end();
builder.end();
return builder.getRoot();
}
@@ -1836,11 +1777,8 @@
replaceCall.startCall("replace");
}
replaceCall.startGroup().startNew(className).string(source);
- for (ActualParameter param : current.getParameters()) {
- if (!param.getSpecification().isSignature()) {
- continue;
- }
- NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
+ for (ActualParameter param : current.getSignatureParameters()) {
+ NodeChildData child = param.getSpecification().getExecution().getChild();
List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
if (types.size() > 1) {
replaceCall.string(implicitTypeName(param));
@@ -1858,7 +1796,7 @@
}
private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) {
- String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
+ String polyClassName = nodePolymorphicClassName(node);
String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization());
CodeTreeBuilder builder = parent.create();
@@ -1869,7 +1807,7 @@
builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end();
builder.startReturn();
- builder.startCall("currentCopy.next0", executeCachedName(node.getGenericPolymorphicSpecialization()));
+ builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME);
addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true, null);
builder.end();
builder.end();
@@ -1877,14 +1815,6 @@
return builder.getRoot();
}
- private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
- for (TemplateMethod listener : node.getSpecializationListeners()) {
- builder.startStatement();
- builder.tree(createTemplateMethodCall(builder, null, listener, listener, null));
- builder.end(); // statement
- }
- }
-
protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) {
TypeData type = executable.getType();
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
@@ -1897,11 +1827,7 @@
boolean returnVoid = type.isVoid();
List executeParameters = new ArrayList<>();
- for (ActualParameter sourceParameter : executable.getParameters()) {
- if (!sourceParameter.getSpecification().isSignature()) {
- continue;
- }
-
+ for (ActualParameter sourceParameter : executable.getSignatureParameters()) {
ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName());
if (targetParameter != null) {
executeParameters.add(targetParameter);
@@ -1968,14 +1894,13 @@
protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List targetParameters,
ActualParameter unexpectedParameter) {
CodeTreeBuilder builder = parent.create();
- NodeData node = specialization.getNode();
for (ActualParameter targetParameter : targetParameters) {
- NodeChildData child = node.findChild(targetParameter.getSpecification().getName());
if (!targetParameter.getSpecification().isSignature()) {
continue;
}
- CodeTree executionExpressions = createExecuteChild(builder, child, sourceExecutable, targetParameter, unexpectedParameter);
- CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, isShortCircuit(child), unexpectedParameter);
+ NodeExecutionData execution = targetParameter.getSpecification().getExecution();
+ CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter);
+ CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, execution.isShortCircuit(), unexpectedParameter);
CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, specialization, targetParameter, unexpectedParameter);
if (shortCircuitTree == executionExpressions) {
@@ -1993,15 +1918,16 @@
return builder.getRoot();
}
- private ExecutableTypeData resolveExecutableType(NodeChildData child, TypeData type) {
- ExecutableTypeData targetExecutable = child.findExecutableType(getContext(), type);
+ private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) {
+ ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(getContext(), type);
if (targetExecutable == null) {
- targetExecutable = child.findAnyGenericExecutableType(getContext());
+ targetExecutable = execution.getChild().findAnyGenericExecutableType(getContext());
}
return targetExecutable;
}
- private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ActualParameter targetParameter, ActualParameter unexpectedParameter) {
+ private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, ActualParameter targetParameter,
+ ActualParameter unexpectedParameter) {
SpecializationData specialization = getModel();
TreeSet possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter);
if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null && possiblePolymorphicTypes.size() > 1) {
@@ -2020,28 +1946,25 @@
builder.string(polymorphicTypeName(targetParameter)).string(" == ").typeLiteral(possiblePolymoprhicType.getPrimitiveType());
builder.end().startBlock();
builder.startStatement();
- builder.tree(createExecuteChildExpression(parent, child, sourceType, new ActualParameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null));
+ builder.tree(createExecuteChildExpression(parent, execution, sourceType, new ActualParameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null));
builder.end();
builder.end();
}
builder.startElseBlock();
- builder.startStatement().tree(createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter)).end();
+ builder.startStatement().tree(createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter)).end();
builder.end();
return builder.getRoot();
} else {
- return createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter);
+ return createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter);
}
}
protected final List getImplicitTypeParamters(SpecializationData model) {
List parameter = new ArrayList<>();
- for (ActualParameter param : model.getParameters()) {
- if (!param.getSpecification().isSignature()) {
- continue;
- }
- NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
+ for (ActualParameter param : model.getSignatureParameters()) {
+ NodeChildData child = param.getSpecification().getExecution().getChild();
List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
if (types.size() > 1) {
parameter.add(param);
@@ -2065,7 +1988,7 @@
return possiblePolymorphicTypes;
}
- private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ActualParameter param, ActualParameter unexpectedParameter) {
+ private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, ActualParameter param, ActualParameter unexpectedParameter) {
CodeTreeBuilder builder = parent.create();
ActualParameter sourceParameter = sourceExecutable.findParameter(param.getLocalName());
String childExecuteName = createExecuteChildMethodName(param, sourceParameter != null);
@@ -2089,19 +2012,20 @@
builder.end();
} else {
- List sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
+ List sourceTypes = execution.getChild().getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null;
if (sourceTypes.size() > 1) {
builder.tree(createExecuteChildImplicitExpressions(parent, param, expectType));
} else {
- builder.tree(createExecuteChildExpression(parent, child, expectType, param, unexpectedParameter, null));
+ builder.tree(createExecuteChildExpression(parent, execution, expectType, param, unexpectedParameter, null));
}
}
return builder.getRoot();
}
private String createExecuteChildMethodName(ActualParameter param, boolean expect) {
- NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
+ NodeExecutionData execution = param.getSpecification().getExecution();
+ NodeChildData child = execution.getChild();
if (child.getExecuteWith().size() > 0) {
return null;
}
@@ -2110,7 +2034,8 @@
return null;
}
String prefix = expect ? "expect" : "execute";
- return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getSpecificationIndex();
+ String suffix = execution.getIndex() > -1 ? String.valueOf(execution.getIndex()) : "";
+ return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + suffix;
}
private List createExecuteChilds(ActualParameter param, Set expectTypes) {
@@ -2155,7 +2080,7 @@
private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, ActualParameter targetParameter, TypeData expectType) {
CodeTreeBuilder builder = parent.create();
NodeData node = getModel().getNode();
- NodeChildData child = node.findChild(targetParameter.getSpecification().getName());
+ NodeExecutionData execution = targetParameter.getSpecification().getExecution();
List sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType());
boolean elseIf = false;
int index = 0;
@@ -2169,18 +2094,18 @@
builder.startElseBlock();
}
- ExecutableTypeData implictExecutableTypeData = child.findExecutableType(getContext(), sourceType);
+ ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(getContext(), sourceType);
if (implictExecutableTypeData == null) {
/*
* For children with executeWith.size() > 0 an executable type may not exist so
* use the generic executable type which is guaranteed to exist. An expect call
* is inserted automatically by #createExecuteExpression.
*/
- implictExecutableTypeData = child.getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), child.getExecuteWith().size());
+ implictExecutableTypeData = execution.getChild().getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), execution.getChild().getExecuteWith().size());
}
- ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(sourceType, targetParameter.getTypeSystemType());
- CodeTree execute = createExecuteChildExpression(builder, child, expectType, targetParameter, null, cast);
+ ImplicitCastData cast = execution.getChild().getNodeData().getTypeSystem().lookupCast(sourceType, targetParameter.getTypeSystemType());
+ CodeTree execute = createExecuteChildExpression(builder, execution, expectType, targetParameter, null, cast);
builder.statement(execute);
builder.end();
index++;
@@ -2188,8 +2113,8 @@
return builder.getRoot();
}
- private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData child, TypeData sourceParameterType, ActualParameter targetParameter, ActualParameter unexpectedParameter,
- ImplicitCastData cast) {
+ private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData execution, TypeData sourceParameterType, ActualParameter targetParameter,
+ ActualParameter unexpectedParameter, ImplicitCastData cast) {
// assignments: targetType <- castTargetType <- castSourceType <- sourceType
TypeData sourceType = sourceParameterType;
TypeData targetType = targetParameter.getTypeSystemType();
@@ -2203,15 +2128,15 @@
CodeTree expression;
if (sourceType == null) {
- ExecutableTypeData targetExecutable = resolveExecutableType(child, castSourceType);
- expression = createExecuteChildExpression(parent, child, targetParameter, targetExecutable, unexpectedParameter);
+ ExecutableTypeData targetExecutable = resolveExecutableType(execution, castSourceType);
+ expression = createExecuteChildExpression(parent, execution, targetExecutable, unexpectedParameter);
sourceType = targetExecutable.getType();
} else {
expression = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter));
}
// target = expectTargetType(implicitCast(expectCastSourceType(source)))
- TypeSystemData typeSystem = child.getNodeData().getTypeSystem();
+ TypeSystemData typeSystem = execution.getChild().getNodeData().getTypeSystem();
expression = createExpectType(typeSystem, sourceType, castSourceType, expression);
expression = createImplicitCast(parent, typeSystem, cast, expression);
expression = createExpectType(typeSystem, castTargetType, targetType, expression);
@@ -2248,32 +2173,32 @@
}
private boolean hasUnexpected(ActualParameter sourceParameter, ActualParameter targetParameter, ActualParameter unexpectedParameter) {
- NodeChildData child = getModel().getNode().findChild(targetParameter.getSpecification().getName());
+ NodeExecutionData execution = targetParameter.getSpecification().getExecution();
if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) {
// check for other polymorphic types
TreeSet polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter);
if (polymorphicTargetTypes.size() > 1) {
for (TypeData polymorphicTargetType : polymorphicTargetTypes) {
- if (hasUnexpectedType(child, sourceParameter, polymorphicTargetType)) {
+ if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) {
return true;
}
}
}
}
- if (hasUnexpectedType(child, sourceParameter, targetParameter.getTypeSystemType())) {
+ if (hasUnexpectedType(execution, sourceParameter, targetParameter.getTypeSystemType())) {
return true;
}
return false;
}
- private boolean hasUnexpectedType(NodeChildData child, ActualParameter sourceParameter, TypeData targetType) {
+ private boolean hasUnexpectedType(NodeExecutionData execution, ActualParameter sourceParameter, TypeData targetType) {
List implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType);
for (TypeData implicitSourceType : implicitSourceTypes) {
TypeData sourceType;
- ExecutableTypeData targetExecutable = resolveExecutableType(child, implicitSourceType);
+ ExecutableTypeData targetExecutable = resolveExecutableType(execution, implicitSourceType);
if (sourceParameter != null) {
sourceType = sourceParameter.getTypeSystemType();
} else {
@@ -2336,8 +2261,7 @@
private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, ActualParameter param) {
NodeData node = specialization.getNode();
- assert !node.getPolymorphicSpecializations().isEmpty();
- SpecializationData generic = node.getGenericPolymorphicSpecialization();
+ SpecializationData polymorphic = node.getPolymorphicSpecialization();
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
builder.startStatement().string(polymorphicTypeName(param)).string(" = ").typeLiteral(getContext().getType(Object.class)).end();
@@ -2345,11 +2269,11 @@
builder.startReturn();
CodeTreeBuilder execute = new CodeTreeBuilder(builder);
- execute.startCall("next0", executeCachedName(generic));
- addInternalValueParameterNames(execute, specialization, generic, param.getLocalName(), true, true, null);
+ execute.startCall("next0", EXECUTE_POLYMORPHIC_NAME);
+ addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, true, null);
execute.end();
- TypeData sourceType = generic.getReturnType().getTypeSystemType();
+ TypeData sourceType = polymorphic.getReturnType().getTypeSystemType();
builder.tree(createExpectExecutableType(node, sourceType, currentExecutable, execute.getRoot()));
@@ -2357,11 +2281,10 @@
return builder.getRoot();
}
- private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter, ExecutableTypeData targetExecutable,
- ActualParameter unexpectedParameter) {
+ private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) {
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
- if (targetChild != null) {
- builder.tree(createAccessChild(builder, targetChild, targetParameter));
+ if (targetExecution != null) {
+ builder.tree(createAccessChild(builder, targetExecution));
builder.string(".");
}
@@ -2375,8 +2298,8 @@
builder.string(parameter.getLocalName());
} else {
- if (index < targetChild.getExecuteWith().size()) {
- NodeChildData child = targetChild.getExecuteWith().get(index);
+ if (index < targetExecution.getChild().getExecuteWith().size()) {
+ NodeChildData child = targetExecution.getChild().getExecuteWith().get(index);
ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName());
List specializationParams = getModel().findParameters(spec);
@@ -2415,31 +2338,31 @@
return builder.getRoot();
}
- private CodeTree createAccessChild(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter) throws AssertionError {
+ private CodeTree createAccessChild(CodeTreeBuilder parent, NodeExecutionData targetExecution) throws AssertionError {
CodeTreeBuilder builder = parent.create();
- Element accessElement = targetChild.getAccessElement();
+ Element accessElement = targetExecution.getChild().getAccessElement();
if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
- builder.string("this.").string(targetChild.getName());
+ builder.string("this.").string(targetExecution.getChild().getName());
} else if (accessElement.getKind() == ElementKind.FIELD) {
builder.string("this.").string(accessElement.getSimpleName().toString());
} else {
throw new AssertionError();
}
- if (targetParameter.getSpecification().isIndexed()) {
- builder.string("[" + targetParameter.getSpecificationIndex() + "]");
+ if (targetExecution.isIndexed()) {
+ builder.string("[" + targetExecution.getIndex() + "]");
}
return builder.getRoot();
}
private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
- NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName());
- if (!isShortCircuit(forField)) {
+ NodeExecutionData execution = parameter.getSpecification().getExecution();
+ if (execution == null || !execution.isShortCircuit()) {
return body;
}
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
- builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam));
+ builder.tree(createShortCircuitValue(builder, specialization, execution, shortCircuitParam, exceptionParam));
builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType()));
builder.startIf().string(shortCircuitParam.getLocalName()).end();
builder.startBlock();
@@ -2454,16 +2377,13 @@
return builder.getRoot();
}
- private boolean isShortCircuit(NodeChildData forField) {
- return forField != null && forField.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT;
- }
-
- private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) {
+ private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeExecutionData execution, ActualParameter shortCircuitParam,
+ ActualParameter exceptionParam) {
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
int shortCircuitIndex = 0;
- for (NodeChildData field : specialization.getNode().getChildren()) {
- if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
- if (field == forField) {
+ for (NodeExecutionData otherExectuion : specialization.getNode().getChildExecutions()) {
+ if (otherExectuion.isShortCircuit()) {
+ if (otherExectuion == execution) {
break;
}
shortCircuitIndex++;
@@ -2543,7 +2463,7 @@
if (nodeGen != null) {
baseType = nodeGen.asType();
}
- CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node, polymorph), baseType, false);
+ CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false);
clazz.getAnnotationMirrors().add(createNodeInfo(node, Kind.POLYMORPHIC));
@@ -2640,8 +2560,12 @@
kind = Kind.GENERIC;
} else if (specialization.isUninitialized()) {
kind = Kind.UNINITIALIZED;
+ } else if (specialization.isPolymorphic()) {
+ kind = Kind.POLYMORPHIC;
+ } else if (specialization.isSpecialized()) {
+ kind = Kind.SPECIALIZED;
} else {
- kind = Kind.SPECIALIZED;
+ throw new AssertionError();
}
clazz.getAnnotationMirrors().add(createNodeInfo(node, kind));
@@ -2747,9 +2671,9 @@
CodeTypeElement clazz = getElement();
- final SpecializationData polymorphic = node.getGenericPolymorphicSpecialization();
-
- ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic));
+ final SpecializationData polymorphic = node.getPolymorphicSpecialization();
+
+ ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_POLYMORPHIC_NAME);
// ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached,
// node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType());
@@ -2767,7 +2691,7 @@
builder.tree(createAppendPolymorphic(builder, specialization));
} else {
CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder);
- elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic));
+ elseBuilder.startReturn().startCall("this.next0", EXECUTE_POLYMORPHIC_NAME);
addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true, null);
elseBuilder.end().end();
@@ -2797,7 +2721,7 @@
builder.startBlock();
String message = "Polymorphic limit reached (" + node.getPolymorphicDepth() + ")";
String castRoot = "(" + baseClassName(node) + ") root";
- builder.tree(createGenericInvoke(builder, node.getGenericPolymorphicSpecialization(), node.getGenericSpecialization(),
+ builder.tree(createGenericInvoke(builder, node.getPolymorphicSpecialization(), node.getGenericSpecialization(),
createReplaceCall(builder, node.getGenericSpecialization(), "root", castRoot, message), null));
builder.end();
@@ -2815,7 +2739,7 @@
builder.declaration(node.getGenericSpecialization().getReturnType().getType(), "result", specializeCall.getRoot());
- CodeTree root = builder.create().cast(nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization())).string("root").getRoot();
+ CodeTree root = builder.create().cast(nodePolymorphicClassName(node)).string("root").getRoot();
builder.startIf().string("this.next0 != null").end().startBlock();
builder.startStatement().string("(").tree(root).string(").").startCall(UPDATE_TYPES_NAME).tree(root).end().end();
builder.end();
@@ -2856,39 +2780,43 @@
int signatureIndex = -1;
for (VariableElement param : method.getParameters()) {
CodeVariableElement var = CodeVariableElement.clone(param);
- ActualParameter actualParameter = execType.getParameters().get(i);
- if (actualParameter.getSpecification().isSignature()) {
- signatureIndex++;
- }
-
+ ActualParameter actualParameter = i < execType.getParameters().size() ? execType.getParameters().get(i) : null;
String name;
- if (evaluated && actualParameter.getSpecification().isSignature()) {
- name = valueNameEvaluated(actualParameter);
- } else {
- name = valueName(actualParameter);
- }
-
- int varArgCount = getModel().getSignatureSize() - signatureIndex;
- if (evaluated && actualParameter.isVarArgs()) {
- ActualParameter baseVarArgs = actualParameter;
- name = valueName(baseVarArgs) + "Args";
-
- builder.startAssert().string(name).string(" != null").end();
- builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end();
- if (varArgCount > 0) {
- List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size());
- for (ActualParameter varArg : varArgsParameter) {
- if (varArgCount <= 0) {
- break;
+ if (actualParameter != null) {
+ if (actualParameter.getSpecification().isSignature()) {
+ signatureIndex++;
+ }
+
+ if (evaluated && actualParameter.getSpecification().isSignature()) {
+ name = valueNameEvaluated(actualParameter);
+ } else {
+ name = valueName(actualParameter);
+ }
+
+ int varArgCount = getModel().getSignatureSize() - signatureIndex;
+ if (evaluated && actualParameter.isTypeVarArgs()) {
+ ActualParameter baseVarArgs = actualParameter;
+ name = valueName(baseVarArgs) + "Args";
+
+ builder.startAssert().string(name).string(" != null").end();
+ builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end();
+ if (varArgCount > 0) {
+ List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size());
+ for (ActualParameter varArg : varArgsParameter) {
+ if (varArgCount <= 0) {
+ break;
+ }
+ TypeMirror type = baseVarArgs.getType();
+ if (type.getKind() == TypeKind.ARRAY) {
+ type = ((ArrayType) type).getComponentType();
+ }
+ builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getTypeVarArgsIndex() + "]");
+ varArgCount--;
}
- TypeMirror type = baseVarArgs.getType();
- if (type.getKind() == TypeKind.ARRAY) {
- type = ((ArrayType) type).getComponentType();
- }
- builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getVarArgsIndex() + "]");
- varArgCount--;
}
}
+ } else {
+ name = "arg" + i;
}
var.setName(name);
method.getParameters().set(i, var);
@@ -2984,7 +2912,7 @@
CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
if (specialization.isPolymorphic()) {
- returnBuilder.startCall("next0", executeCachedName(specialization));
+ returnBuilder.startCall("next0", EXECUTE_POLYMORPHIC_NAME);
addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true, null);
returnBuilder.end();
} else if (specialization.isUninitialized()) {
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,54 +28,61 @@
import javax.lang.model.type.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
import com.oracle.truffle.dsl.processor.template.*;
import com.oracle.truffle.dsl.processor.typesystem.*;
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 List declaredNodes = new ArrayList<>();
- private boolean nodeContainer;
- private TypeSystemData typeSystem;
- private List children;
- private List fields;
- private TypeMirror nodeType;
+ private final TypeSystemData typeSystem;
+ private final List children;
+ private final List childExecutions;
+ private final List fields;
+ private final List assumptions;
+
private ParameterSpec instanceParameterSpec;
- private List specializations;
- private List polymorphicSpecializations;
- private SpecializationData genericPolymorphicSpecialization;
- private List specializationListeners;
+ private final List specializations = new ArrayList<>();
+ private final List shortCircuits = new ArrayList<>();
+ private final List casts = new ArrayList<>();
private Map> executableTypes;
- private List shortCircuits;
- private List assumptions;
- private List casts;
private int polymorphicDepth = -1;
- private String shortName;
- public NodeData(TypeElement type, String id) {
+ public NodeData(TypeElement type, String shortName, TypeSystemData typeSystem, List children, List executions, List fields,
+ List assumptions, int polymorphicDepth) {
super(type, null, null);
- this.nodeId = id;
+ this.nodeId = type.getSimpleName().toString();
+ this.shortName = shortName;
+ this.typeSystem = typeSystem;
+ this.fields = fields;
+ this.children = children;
+ this.childExecutions = executions;
+ this.assumptions = assumptions;
+ this.polymorphicDepth = polymorphicDepth;
+
+ if (children != null) {
+ for (NodeChildData child : children) {
+ child.setParentNode(this);
+ }
+ }
}
- public NodeData(NodeData splitSource, String templateMethodName, String nodeId) {
- super(splitSource.getTemplateType(), templateMethodName, null);
- this.nodeId = nodeId;
- this.declaringNode = splitSource.declaringNode;
- this.declaredNodes = splitSource.declaredNodes;
- this.typeSystem = splitSource.typeSystem;
- this.nodeType = splitSource.nodeType;
- this.specializations = splitSource.specializations;
- this.specializationListeners = splitSource.specializationListeners;
- this.executableTypes = splitSource.executableTypes;
- this.shortCircuits = splitSource.shortCircuits;
- this.fields = splitSource.fields;
- this.children = splitSource.children;
- this.assumptions = splitSource.assumptions;
+ public NodeData(TypeElement type) {
+ this(type, null, null, null, null, null, null, -1);
+ }
+
+ public void addEnclosedNode(NodeData node) {
+ this.enclosingNodes.add(node);
+ node.declaringNode = this;
+ }
+
+ public List getChildExecutions() {
+ return childExecutions;
}
public int getSignatureSize() {
@@ -114,7 +121,7 @@
return polymorphicDepth > 1;
}
- void setPolymorphicDepth(int polymorphicDepth) {
+ public void setPolymorphicDepth(int polymorphicDepth) {
this.polymorphicDepth = polymorphicDepth;
}
@@ -122,43 +129,19 @@
return casts;
}
- void setCasts(List casts) {
- this.casts = casts;
- }
-
- void setShortName(String shortName) {
- this.shortName = shortName;
- }
-
public String getShortName() {
return shortName;
}
- public boolean isNodeContainer() {
- return nodeContainer;
- }
-
- void setTypeSystem(TypeSystemData typeSystem) {
- this.typeSystem = typeSystem;
- }
-
- void setFields(List fields) {
- this.fields = fields;
- }
-
public List getFields() {
return fields;
}
- void setNodeContainer(boolean splitByMethodName) {
- this.nodeContainer = splitByMethodName;
- }
-
@Override
protected List findChildContainers() {
List containerChildren = new ArrayList<>();
- if (declaredNodes != null) {
- containerChildren.addAll(declaredNodes);
+ if (enclosingNodes != null) {
+ containerChildren.addAll(enclosingNodes);
}
if (typeSystem != null) {
containerChildren.add(typeSystem);
@@ -170,9 +153,6 @@
}
}
}
- if (specializationListeners != null) {
- containerChildren.addAll(specializationListeners);
- }
if (executableTypes != null) {
containerChildren.addAll(getExecutableTypes());
}
@@ -204,16 +184,9 @@
}
public TypeMirror getNodeType() {
- if (nodeType != null) {
- return nodeType;
- }
return getTemplateType().asType();
}
- void setAssumptions(List assumptions) {
- this.assumptions = assumptions;
- }
-
public List getAssumptions() {
return assumptions;
}
@@ -228,7 +201,7 @@
boolean noSpecialization = true;
for (SpecializationData specialization : specializations) {
- noSpecialization = noSpecialization && specialization.isGeneric() || specialization.isUninitialized();
+ noSpecialization = noSpecialization && !specialization.isSpecialized();
}
return !noSpecialization;
}
@@ -246,7 +219,7 @@
public List getNodeDeclaringChildren() {
List nodeChildren = new ArrayList<>();
- for (NodeData child : getDeclaredNodes()) {
+ for (NodeData child : getEnclosingNodes()) {
if (child.needsFactory()) {
nodeChildren.add(child);
}
@@ -255,24 +228,12 @@
return nodeChildren;
}
- void setDeclaredNodes(List declaredChildren) {
- this.declaredNodes = declaredChildren;
-
- for (NodeData child : declaredChildren) {
- child.declaringNode = this;
- }
- }
-
- public NodeData getParent() {
+ public NodeData getDeclaringNode() {
return declaringNode;
}
- public List getDeclaredNodes() {
- return declaredNodes;
- }
-
- public void setNodeType(TypeMirror nodeType) {
- this.nodeType = nodeType;
+ public List getEnclosingNodes() {
+ return enclosingNodes;
}
public List getAllTemplateMethods() {
@@ -282,7 +243,6 @@
methods.add(specialization);
}
- methods.addAll(getSpecializationListeners());
methods.addAll(getExecutableTypes());
methods.addAll(getShortCircuits());
if (getCasts() != null) {
@@ -374,16 +334,6 @@
return result;
}
- public NodeChildData[] filterFields(ExecutionKind usage) {
- List filteredFields = new ArrayList<>();
- for (NodeChildData field : getChildren()) {
- if (usage == null || field.getExecutionKind() == usage) {
- filteredFields.add(field);
- }
- }
- return filteredFields.toArray(new NodeChildData[filteredFields.size()]);
- }
-
public boolean needsRewrites(ProcessorContext context) {
boolean needsRewrites = false;
@@ -396,6 +346,15 @@
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.isGeneric()) {
@@ -438,13 +397,12 @@
dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
dumpProperty(builder, indent, "specializations", getSpecializations());
dumpProperty(builder, indent, "polymorphicDepth", getPolymorphicDepth());
- dumpProperty(builder, indent, "polymorphic", getPolymorphicSpecializations());
dumpProperty(builder, indent, "assumptions", getAssumptions());
dumpProperty(builder, indent, "casts", getCasts());
dumpProperty(builder, indent, "messages", collectMessages());
- if (getDeclaredNodes().size() > 0) {
+ if (getEnclosingNodes().size() > 0) {
builder.append(String.format("\n%s children = [", indent));
- for (NodeData node : getDeclaredNodes()) {
+ for (NodeData node : getEnclosingNodes()) {
builder.append("\n");
builder.append(node.dump(level + 1));
}
@@ -490,6 +448,18 @@
return b.toString();
}
+ public NodeExecutionData findExecution(String name) {
+ if (getChildExecutions() == null) {
+ return null;
+ }
+ for (NodeExecutionData execution : getChildExecutions()) {
+ if (execution.getName().equals(name)) {
+ return execution;
+ }
+ }
+ return null;
+ }
+
public NodeChildData findChild(String name) {
for (NodeChildData field : getChildren()) {
if (field.getName().equals(name)) {
@@ -503,30 +473,8 @@
return children;
}
- void setChildren(List fields) {
- this.children = fields;
- }
-
public List getSpecializations() {
- return getSpecializations(false);
- }
-
- public List getSpecializations(boolean userDefinedOnly) {
- if (userDefinedOnly) {
- List specs = new ArrayList<>();
- for (SpecializationData spec : specializations) {
- if (spec.getMethod() != null) {
- specs.add(spec);
- }
- }
- return specs;
- } else {
- return specializations;
- }
- }
-
- public List getSpecializationListeners() {
- return specializationListeners;
+ return specializations;
}
public List getExecutableTypes() {
@@ -537,43 +485,10 @@
return shortCircuits;
}
- void setSpecializations(List specializations) {
- this.specializations = specializations;
- if (this.specializations != null) {
- for (SpecializationData specialization : specializations) {
- specialization.setNode(this);
- }
- }
- }
-
- void setPolymorphicSpecializations(List polymorphicSpecializations) {
- this.polymorphicSpecializations = polymorphicSpecializations;
- }
-
- public List getPolymorphicSpecializations() {
- return polymorphicSpecializations;
- }
-
- void setGenericPolymorphicSpecialization(SpecializationData genericPolymoprhicSpecialization) {
- this.genericPolymorphicSpecialization = genericPolymoprhicSpecialization;
- }
-
- public SpecializationData getGenericPolymorphicSpecialization() {
- return genericPolymorphicSpecialization;
- }
-
- void setSpecializationListeners(List specializationListeners) {
- this.specializationListeners = specializationListeners;
- }
-
- void setExecutableTypes(Map> executableTypes) {
+ public void setExecutableTypes(Map> executableTypes) {
this.executableTypes = executableTypes;
}
- void setShortCircuits(List shortCircuits) {
- this.shortCircuits = shortCircuits;
- }
-
@Override
public String toString() {
return getClass().getSimpleName() + "[" + getNodeId() + "]";
@@ -593,4 +508,5 @@
public int compareTo(NodeData o) {
return getNodeId().compareTo(o.getNodeId());
}
+
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java Tue Jan 07 18:53:04 2014 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.node;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+
+public class NodeExecutionData {
+
+ private final NodeChildData child;
+ private final String name;
+ private final int index;
+ private final boolean shortCircuit;
+
+ public NodeExecutionData(NodeChildData child, int index, boolean shortCircuit) {
+ this.child = child;
+ this.index = index;
+ this.shortCircuit = shortCircuit;
+ this.name = createName();
+ }
+
+ private String createName() {
+ if (isIndexed()) {
+ return child.getName() + index;
+ }
+ return child.getName();
+ }
+
+ 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 getIndex() {
+ return index;
+ }
+
+ public boolean isIndexed() {
+ return index > -1;
+ }
+
+ public boolean isShortCircuit() {
+ return shortCircuit;
+ }
+
+ public String getShortCircuitId() {
+ return createShortCircuitId(child, index);
+ }
+
+ public static String createShortCircuitId(NodeChildData child, int varArgsIndex) {
+ String shortCircuitName = child.getName();
+ if (child.getCardinality().isMany()) {
+ shortCircuitName = shortCircuitName + "[" + varArgsIndex + "]";
+ }
+ return shortCircuitName;
+ }
+
+}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,7 +28,6 @@
import javax.lang.model.type.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
import com.oracle.truffle.dsl.processor.template.*;
public abstract class NodeMethodParser extends TemplateMethodParser {
@@ -41,10 +40,9 @@
return template;
}
- @SuppressWarnings("unused")
- protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
- ParameterSpec spec = new ParameterSpec(valueName, nodeTypeMirrors(nodeData));
- spec.setSignature(true);
+ protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) {
+ ParameterSpec spec = new ParameterSpec(execution.getName(), nodeTypeMirrors(execution.getChild().getNodeData()));
+ spec.setExecution(execution);
return spec;
}
@@ -61,7 +59,7 @@
}
protected ParameterSpec createReturnParameterSpec() {
- return createValueParameterSpec("returnValue", getNode(), 0);
+ return new ParameterSpec("returnValue", nodeTypeMirrors(getNode()));
}
@Override
@@ -85,31 +83,21 @@
return methodSpec;
}
- public void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec methodSpec) {
- // children are null when parsing executable types
- if (getNode().getChildren() != null) {
- for (NodeChildData child : getNode().getChildren()) {
- String valueName = child.getName();
- if (breakName != null && valueName.equals(breakName)) {
- break;
- }
- if (child.getExecutionKind() == ExecutionKind.DEFAULT) {
- ParameterSpec spec = createValueParameterSpec(child.getName(), child.getNodeData(), child.getExecuteWith().size());
- if (child.getCardinality().isMany()) {
- spec.setCardinality(Cardinality.MANY);
- spec.setIndexed(true);
- }
- methodSpec.addRequired(spec);
- } else if (child.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
+ public void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec spec) {
+ if (getNode().getChildren() == null) {
+ // children are null when parsing executable types
+ return;
+ }
- if (shortCircuitsEnabled) {
- methodSpec.addRequired(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class)));
- }
- methodSpec.addRequired(createValueParameterSpec(valueName, child.getNodeData(), child.getExecuteWith().size()));
- } else {
- assert false;
- }
+ for (NodeExecutionData execution : getNode().getChildExecutions()) {
+ if (breakName != null && execution.getShortCircuitId().equals(breakName)) {
+ break;
}
+
+ if (execution.isShortCircuit() && shortCircuitsEnabled) {
+ spec.addRequired(new ParameterSpec(shortCircuitValueName(execution.getName()), getContext().getType(boolean.class)));
+ }
+ spec.addRequired(createValueParameterSpec(execution));
}
}
@@ -121,7 +109,7 @@
protected void addDefaultFieldMethodSpec(MethodSpec methodSpec) {
for (NodeFieldData field : getNode().getFields()) {
- if (getNode().isNodeContainer() || field.getGetter() == null) {
+ if (field.getGetter() == null) {
ParameterSpec spec = new ParameterSpec(field.getName(), field.getType());
spec.setLocal(true);
methodSpec.addOptional(spec);
@@ -130,6 +118,9 @@
}
protected void addDefaultImplicitThis(ExecutableElement method, MethodSpec methodSpec) {
+ if (method == null) {
+ return;
+ }
TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) {
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -34,15 +34,15 @@
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.dsl.processor.*;
import com.oracle.truffle.dsl.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind;
+import com.oracle.truffle.dsl.processor.node.SpecializationData.*;
import com.oracle.truffle.dsl.processor.template.*;
-import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature;
+import com.oracle.truffle.dsl.processor.template.TemplateMethod.TypeSignature;
import com.oracle.truffle.dsl.processor.typesystem.*;
-public class NodeParser extends TemplateParser {
+public class NodeParser extends AbstractParser {
- public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class,
- NodeContainer.class, NodeChild.class, NodeChildren.class, NodeId.class);
+ public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, NodeChild.class,
+ NodeChildren.class);
private Map parsedNodes;
@@ -52,7 +52,6 @@
@Override
protected NodeData parse(Element element, AnnotationMirror mirror) {
- assert element instanceof TypeElement;
NodeData node = null;
try {
parsedNodes = new HashMap<>();
@@ -73,7 +72,7 @@
@Override
protected NodeData filterErrorElements(NodeData model) {
- for (Iterator iterator = model.getDeclaredNodes().iterator(); iterator.hasNext();) {
+ for (Iterator iterator = model.getEnclosingNodes().iterator(); iterator.hasNext();) {
NodeData node = filterErrorElements(iterator.next());
if (node == null) {
iterator.remove();
@@ -106,29 +105,27 @@
return parsedNodes.get(typeName);
}
- List extends TypeElement> types = ElementFilter.typesIn(rootType.getEnclosedElements());
-
- List children = new ArrayList<>();
- for (TypeElement childElement : types) {
- NodeData childNode = resolveNode(childElement);
- if (childNode != null) {
- children.add(childNode);
+ List enclosedNodes = new ArrayList<>();
+ for (TypeElement enclosedType : ElementFilter.typesIn(rootType.getEnclosedElements())) {
+ NodeData enclosedChild = resolveNode(enclosedType);
+ if (enclosedChild != null) {
+ enclosedNodes.add(enclosedChild);
}
}
- NodeData rootNode = parseNode(rootType);
- if (rootNode == null && children.size() > 0) {
- rootNode = new NodeData(rootType, rootType.getSimpleName().toString());
+ NodeData node = parseNode(rootType);
+ if (node == null && !enclosedNodes.isEmpty()) {
+ node = new NodeData(rootType);
}
- parsedNodes.put(typeName, rootNode);
-
- if (rootNode != null) {
- children.addAll(rootNode.getDeclaredNodes());
- rootNode.setDeclaredNodes(children);
+ if (node != null) {
+ for (NodeData enclosedNode : enclosedNodes) {
+ node.addEnclosedNode(enclosedNode);
+ }
}
- return rootNode;
+ parsedNodes.put(typeName, node);
+ return node;
}
private NodeData parseNode(TypeElement originalTemplateType) {
@@ -140,174 +137,69 @@
return null;
}
- List lookupTypes = findSuperClasses(new ArrayList(), templateType);
- Collections.reverse(lookupTypes);
-
- AnnotationMirror nodeClass = findFirstAnnotation(lookupTypes, NodeContainer.class);
- TypeMirror nodeType = null;
- if (Utils.isAssignable(context, templateType.asType(), context.getTruffleTypes().getNode())) {
- nodeType = templateType.asType();
- }
- if (nodeClass != null) {
- nodeType = inheritType(nodeClass, "value", nodeType);
- }
-
- if (nodeType == null) {
+ List lookupTypes = collectSuperClasses(new ArrayList(), templateType);
+ if (!Utils.isAssignable(context, templateType.asType(), context.getTruffleTypes().getNode())) {
return null;
}
- Elements elementUtil = context.getEnvironment().getElementUtils();
- Set elementSet = new HashSet<>(elementUtil.getAllMembers(templateType));
- if (!Utils.typeEquals(templateType.asType(), nodeType)) {
- elementSet.addAll(elementUtil.getAllMembers(Utils.fromTypeMirror(nodeType)));
-
- List nodeLookupTypes = findSuperClasses(new ArrayList(), Utils.fromTypeMirror(nodeType));
- Collections.reverse(nodeLookupTypes);
- lookupTypes.addAll(nodeLookupTypes);
+ List extends Element> elements = context.getEnvironment().getElementUtils().getAllMembers(templateType);
- Set types = new HashSet<>();
- for (ListIterator iterator = lookupTypes.listIterator(); iterator.hasNext();) {
- TypeElement typeElement = iterator.next();
- if (types.contains(typeElement)) {
- iterator.remove();
- } else {
- types.add(typeElement);
- }
- }
- }
- List elements = new ArrayList<>(elementSet);
-
- NodeData node = parseNodeData(templateType, nodeType, elements, lookupTypes);
-
+ NodeData node = parseNodeData(templateType, elements, lookupTypes);
if (node.hasErrors()) {
return node; // error sync point
}
- parseMethods(node, elements);
+ initializeChildren(node);
+
+ node.getSpecializations().addAll(new SpecializationMethodParser(context, node).parse(elements));
+ node.getSpecializations().addAll(new GenericParser(context, node).parse(elements));
+ node.getCasts().addAll(new CreateCastParser(context, node).parse(elements));
+ node.getShortCircuits().addAll(new ShortCircuitParser(context, node).parse(elements));
if (node.hasErrors()) {
- return node;
- }
-
- List nodes;
-
- if (node.isNodeContainer()) {
- nodes = splitNodeData(node);
- } else {
- nodes = new ArrayList<>();
- nodes.add(node);
+ return node; // error sync point
}
- for (NodeData splittedNode : nodes) {
- if (templateType.getModifiers().contains(Modifier.PRIVATE) && splittedNode.getSpecializations().size() > 0) {
- splittedNode.addError("Classes containing a @%s annotation must not be private.", Specialization.class.getSimpleName());
- }
+ verifySpecializationSameLength(node);
+ initializeSpecializations(elements, node);
+ initializeShortCircuits(node); // requires specializations and polymorphic specializations
- finalizeSpecializations(elements, splittedNode);
- verifyNode(splittedNode, elements);
- expandExecutableTypeVarArgs(splittedNode);
- createPolymorphicSpecializations(splittedNode);
- assignShortCircuitsToSpecializations(splittedNode);
- }
-
- if (node.isNodeContainer()) {
- node.setDeclaredNodes(nodes);
- node.setSpecializationListeners(new ArrayList());
- node.setSpecializations(new ArrayList());
- }
+ verifyVisibilities(node);
+ verifySpecializationOrder(node);
+ verifyMissingAbstractMethods(node, elements);
+ verifyConstructors(node);
+ verifyNamingConvention(node.getShortCircuits(), "needs");
+ verifySpecializationThrows(node);
return node;
}
- private static void expandExecutableTypeVarArgs(NodeData node) {
- for (ExecutableTypeData executableMethod : node.getExecutableTypes()) {
- if (!(executableMethod.getMethod().isVarArgs() && executableMethod.getSpecification().isVariableRequiredArguments())) {
- continue;
- }
- int expandArguments = node.getSignatureSize() - executableMethod.getSignatureSize();
- if (expandArguments > 0) {
- int signatureSize = executableMethod.getSignatureSize();
- ActualParameter parameter = executableMethod.getSignatureParameter(signatureSize - 1);
- for (int i = 0; i < expandArguments; i++) {
- int newVarArgsIndex = parameter.getVarArgsIndex() + i + 1;
- int newSpecificationIndex = parameter.getSpecificationIndex() + i + 1;
- executableMethod.getParameters().add(
- new ActualParameter(parameter.getSpecification(), parameter.getTypeSystemType(), newSpecificationIndex, newVarArgsIndex, parameter.isImplicit()));
- }
-
- }
- }
- }
-
- private void createPolymorphicSpecializations(NodeData node) {
- if (!node.needsRewrites(context) || !node.isPolymorphic()) {
- node.setPolymorphicSpecializations(Collections. emptyList());
- return;
- }
-
- SpecializationData generic = node.getGenericSpecialization();
-
- List polymorphicSignature = new ArrayList<>();
- // TODO we should support more optimized for boxing
- // List updatePolymorphic = generic.getReturnTypeAndParameters();
- List updatePolymorphic = Arrays.asList();
- for (ActualParameter genericParameter : updatePolymorphic) {
- if (!genericParameter.getSpecification().isSignature()) {
- continue;
- }
-
- Set usedTypes = new HashSet<>();
- for (SpecializationData specialization : node.getSpecializations()) {
- if (!specialization.isSpecialized()) {
- continue;
- }
- ActualParameter parameter = specialization.findParameter(genericParameter.getLocalName());
- if (parameter == null) {
- throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName());
- }
- usedTypes.add(parameter.getTypeSystemType());
- }
-
- TypeData polymorphicType;
- if (usedTypes.size() == 1) {
- polymorphicType = usedTypes.iterator().next();
- } else {
- polymorphicType = node.getTypeSystem().getGenericTypeData();
- }
- polymorphicSignature.add(polymorphicType);
- }
-
- SpecializationData specialization = new SpecializationData(generic, false, false, true);
- specialization.updateSignature(new Signature(polymorphicSignature));
- specialization.setNode(node);
- node.setGenericPolymorphicSpecialization(specialization);
- // TODO remove polymoprhic specializations
- node.setPolymorphicSpecializations(Collections. emptyList());
- }
-
- private NodeData parseNodeData(TypeElement templateType, TypeMirror nodeType, List extends Element> elements, List typeHierarchy) {
- NodeData nodeData = new NodeData(templateType, templateType.getSimpleName().toString());
-
+ private NodeData parseNodeData(TypeElement templateType, List extends Element> elements, List typeHierarchy) {
AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
if (typeSystemMirror == null) {
- nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), Utils.getQualifiedName(nodeType));
+ NodeData nodeData = new NodeData(templateType);
+ nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), Utils.getQualifiedName(templateType));
return nodeData;
}
- TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
- final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
+ TypeMirror typeSystemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
+ final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSystemType, true);
if (typeSystem == null) {
- nodeData.addError("The used type system '%s' is invalid or not a Node.", Utils.getQualifiedName(typeSytemType));
+ NodeData nodeData = new NodeData(templateType);
+ nodeData.addError("The used type system '%s' is invalid or not a Node.", Utils.getQualifiedName(typeSystemType));
return nodeData;
}
AnnotationMirror polymorphicMirror = findFirstAnnotation(typeHierarchy, PolymorphicLimit.class);
+ int polymorphicLimit = -1;
if (polymorphicMirror != null) {
AnnotationValue limitValue = Utils.getAnnotationValue(polymorphicMirror, "value");
- int polymorphicLimit = Utils.getAnnotationValue(Integer.class, polymorphicMirror, "value");
- if (polymorphicLimit < 1) {
+ int customPolymorphicLimit = Utils.getAnnotationValue(Integer.class, polymorphicMirror, "value");
+ if (customPolymorphicLimit < 1) {
+ NodeData nodeData = new NodeData(templateType);
nodeData.addError(limitValue, "Invalid polymorphic limit %s.", polymorphicLimit);
+ return nodeData;
}
- nodeData.setPolymorphicDepth(polymorphicLimit);
+ polymorphicLimit = customPolymorphicLimit;
}
List assumptionsList = new ArrayList<>();
@@ -325,22 +217,19 @@
}
}
AnnotationMirror nodeInfoMirror = findFirstAnnotation(typeHierarchy, NodeInfo.class);
+ String shortName = null;
if (nodeInfoMirror != null) {
- nodeData.setShortName(Utils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"));
+ shortName = Utils.getAnnotationValue(String.class, nodeInfoMirror, "shortName");
}
- nodeData.setAssumptions(new ArrayList<>(assumptionsList));
- nodeData.setNodeType(nodeType);
- AnnotationMirror nodeContainer = findFirstAnnotation(typeHierarchy, NodeContainer.class);
- nodeData.setNodeContainer(nodeContainer != null);
- nodeData.setTypeSystem(typeSystem);
- nodeData.setFields(parseFields(typeHierarchy, elements));
- nodeData.setChildren(parseChildren(nodeData, elements, typeHierarchy));
+ List fields = parseFields(typeHierarchy, elements);
+ List children = parseChildren(elements, typeHierarchy);
+ List executions = parseExecutions(children, elements);
+
+ NodeData nodeData = new NodeData(templateType, shortName, typeSystem, children, executions, fields, assumptionsList, polymorphicLimit);
nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)));
- // resolveChildren invokes cyclic parsing.
parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
- resolveChildren(nodeData);
return nodeData;
}
@@ -389,28 +278,7 @@
return fields;
}
- private void resolveChildren(NodeData node) {
- for (NodeChildData nodeChild : node.getChildren()) {
- NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeChild.getNodeType()));
- nodeChild.setNode(fieldNodeData);
- if (fieldNodeData == null) {
- nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(nodeChild.getNodeType()));
- } else if (!Utils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) {
- nodeChild.addError("The @%s of the node and the @%s of the @%s does not match. %s != %s. ", TypeSystem.class.getSimpleName(), TypeSystem.class.getSimpleName(),
- NodeChild.class.getSimpleName(), Utils.getSimpleName(node.getTypeSystem().getTemplateType()), Utils.getSimpleName(fieldNodeData.getTypeSystem().getTemplateType()));
- }
- if (fieldNodeData != null) {
- List types = nodeChild.findGenericExecutableTypes(context);
- if (types.isEmpty()) {
- AnnotationValue executeWithValue = Utils.getAnnotationValue(nodeChild.getMessageAnnotation(), "executeWith");
- nodeChild.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", nodeChild.getExecuteWith().size(),
- Utils.getSimpleName(nodeChild.getNodeType()));
- }
- }
- }
- }
-
- private List parseChildren(NodeData parent, List extends Element> elements, final List typeHierarchy) {
+ private List parseChildren(List extends Element> elements, final List typeHierarchy) {
Set shortCircuits = new HashSet<>();
for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
@@ -435,7 +303,6 @@
List typeHierarchyReversed = new ArrayList<>(typeHierarchy);
Collections.reverse(typeHierarchyReversed);
for (TypeElement type : typeHierarchyReversed) {
- AnnotationMirror nodeClassMirror = Utils.findAnnotationMirror(processingEnv, type, NodeContainer.class);
AnnotationMirror nodeChildrenMirror = Utils.findAnnotationMirror(processingEnv, type, NodeChildren.class);
TypeMirror nodeClassType = type.getSuperclass();
@@ -443,10 +310,6 @@
nodeClassType = null;
}
- if (nodeClassMirror != null) {
- nodeClassType = inheritType(nodeClassMirror, "value", nodeClassType);
- }
-
List children = Utils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class);
int index = 0;
for (AnnotationMirror childMirror : children) {
@@ -470,16 +333,13 @@
Element getter = findGetter(elements, name, childType);
- ExecutionKind kind = ExecutionKind.DEFAULT;
- if (shortCircuits.contains(name)) {
- kind = ExecutionKind.SHORT_CIRCUIT;
- }
-
- NodeChildData nodeChild = new NodeChildData(parent, type, childMirror, name, childType, originalChildType, getter, cardinality, kind);
+ NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality);
parsedChildren.add(nodeChild);
- verifyNodeChild(nodeChild);
+ if (nodeChild.getNodeType() == null) {
+ nodeChild.addError("No valid node type could be resoleved.");
+ }
if (nodeChild.hasErrors()) {
continue;
}
@@ -541,153 +401,182 @@
return filteredChildren;
}
- private void parseMethods(final NodeData node, List elements) {
- node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements));
- node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements));
- List generics = new GenericParser(context, node).parse(elements);
- List specializations = new SpecializationMethodParser(context, node).parse(elements);
- node.setCasts(new CreateCastParser(context, node).parse(elements));
+ private List parseExecutions(List children, List extends Element> elements) {
+ if (children == null) {
+ return null;
+ }
+
+ // pre-parse short circuits
+ Set shortCircuits = new HashSet<>();
+ List methods = ElementFilter.methodsIn(elements);
+ for (ExecutableElement method : methods) {
+ AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
+ if (mirror != null) {
+ shortCircuits.add(Utils.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();
+ }
+ }
+
+ // pre-parse specializations
+ for (ExecutableElement method : methods) {
+ AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, Specialization.class);
+ if (mirror == null) {
+ continue;
+ }
- List allSpecializations = new ArrayList<>();
- allSpecializations.addAll(generics);
- allSpecializations.addAll(specializations);
+ int currentArgumentCount = 0;
+ boolean skipShortCircuit = false;
+ for (VariableElement var : method.getParameters()) {
+ TypeMirror type = var.asType();
+ if (currentArgumentCount == 0) {
+ // skip optionals
+ if (Utils.typeEquals(type, context.getTruffleTypes().getFrame())) {
+ continue;
+ }
+ // TODO skip optional fields?
+ }
+ int childIndex = currentArgumentCount < children.size() ? currentArgumentCount : children.size() - 1;
+ if (childIndex == -1) {
+ continue;
+ }
+ if (!skipShortCircuit) {
+ NodeChildData child = children.get(childIndex);
+ if (shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, currentArgumentCount - childIndex))) {
+ skipShortCircuit = true;
+ continue;
+ }
+ } else {
+ skipShortCircuit = false;
+ }
- node.setSpecializations(allSpecializations);
+ currentArgumentCount++;
+ }
+ maxSignatureSize = Math.max(maxSignatureSize, currentArgumentCount);
+ }
+
+ List executions = new ArrayList<>();
+ for (int i = 0; i < maxSignatureSize; i++) {
+ int childIndex = i;
+ boolean varArg = false;
+ if (childIndex >= children.size() - 1) {
+ if (hasVarArgs) {
+ childIndex = children.size() - 1;
+ varArg = hasVarArgs;
+ } else if (childIndex >= children.size()) {
+ break;
+ }
+ }
+ int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1;
+ NodeChildData child = children.get(childIndex);
+ boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, varArgsIndex));
+ executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit));
+ }
+ return executions;
}
- private static List splitNodeData(NodeData node) {
- SortedMap> groupedSpecializations = groupByNodeId(node.getSpecializations());
- SortedMap> groupedListeners = groupByNodeId(node.getSpecializationListeners());
- SortedMap> groupedCasts = groupByNodeId(node.getCasts());
-
- Set ids = new TreeSet<>();
- ids.addAll(groupedSpecializations.keySet());
- ids.addAll(groupedListeners.keySet());
+ private static Map> groupExecutableTypes(List executableTypes) {
+ Map> groupedTypes = new TreeMap<>();
+ for (ExecutableTypeData type : executableTypes) {
+ int evaluatedCount = type.getEvaluatedCount();
- List splitted = new ArrayList<>();
- for (String id : ids) {
- List specializations = groupedSpecializations.get(id);
- List listeners = groupedListeners.get(id);
- List casts = groupedCasts.get(id);
-
- if (specializations == null) {
- specializations = new ArrayList<>();
+ List types = groupedTypes.get(evaluatedCount);
+ if (types == null) {
+ types = new ArrayList<>();
+ groupedTypes.put(evaluatedCount, types);
}
-
- if (listeners == null) {
- listeners = new ArrayList<>();
- }
-
- String nodeId = node.getNodeId();
- if (nodeId.endsWith("Node") && !nodeId.equals("Node")) {
- nodeId = nodeId.substring(0, nodeId.length() - 4);
- }
- String newNodeId = nodeId + Utils.firstLetterUpperCase(id);
- NodeData copy = new NodeData(node, id, newNodeId);
-
- copy.setSpecializations(specializations);
- copy.setSpecializationListeners(listeners);
- copy.setCasts(casts);
-
- splitted.add(copy);
+ types.add(type);
}
- node.setSpecializations(new ArrayList());
- node.setSpecializationListeners(new ArrayList());
- node.setCasts(new ArrayList());
-
- return splitted;
+ for (List types : groupedTypes.values()) {
+ Collections.sort(types);
+ }
+ return groupedTypes;
}
- private void finalizeSpecializations(List elements, final NodeData node) {
- List specializations = new ArrayList<>(node.getSpecializations());
+ private void initializeChildren(NodeData node) {
+ for (NodeChildData nodeChild : node.getChildren()) {
+ NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeChild.getNodeType()));
+ nodeChild.setNode(fieldNodeData);
+ if (fieldNodeData == null) {
+ nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(nodeChild.getNodeType()));
+ } else if (!Utils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) {
+ nodeChild.addError("The @%s of the node and the @%s of the @%s does not match. %s != %s. ", TypeSystem.class.getSimpleName(), TypeSystem.class.getSimpleName(),
+ NodeChild.class.getSimpleName(), Utils.getSimpleName(node.getTypeSystem().getTemplateType()), Utils.getSimpleName(fieldNodeData.getTypeSystem().getTemplateType()));
+ }
+ if (fieldNodeData != null) {
+ List types = nodeChild.findGenericExecutableTypes(context);
+ if (types.isEmpty()) {
+ AnnotationValue executeWithValue = Utils.getAnnotationValue(nodeChild.getMessageAnnotation(), "executeWith");
+ nodeChild.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", nodeChild.getExecuteWith().size(),
+ Utils.getSimpleName(nodeChild.getNodeType()));
+ }
+ }
+ }
+ }
- if (specializations.isEmpty()) {
+ private void initializeSpecializations(List extends Element> elements, final NodeData node) {
+ if (node.getSpecializations().isEmpty()) {
return;
}
- for (SpecializationData specialization : specializations) {
- matchGuards(elements, specialization);
- }
-
- List generics = new ArrayList<>();
- for (SpecializationData spec : specializations) {
- if (spec.isGeneric()) {
- generics.add(spec);
+ for (SpecializationData specialization : node.getSpecializations()) {
+ if (!specialization.isSpecialized()) {
+ continue;
}
- }
-
- if (generics.size() == 1 && specializations.size() == 1) {
- for (SpecializationData generic : generics) {
- generic.addError("@%s defined but no @%s.", Generic.class.getSimpleName(), Specialization.class.getSimpleName());
- }
- }
-
- SpecializationData genericSpecialization = null;
- if (generics.size() > 1) {
- for (SpecializationData generic : generics) {
- generic.addError("Only @%s is allowed per operation.", Generic.class.getSimpleName());
- }
- return;
- } else if (generics.size() == 1) {
- genericSpecialization = generics.get(0);
- } else if (node.needsRewrites(context)) {
- genericSpecialization = createGenericSpecialization(node, specializations);
- specializations.add(genericSpecialization);
+ initializeGuards(elements, specialization);
}
- if (genericSpecialization != null) {
- for (ActualParameter parameter : genericSpecialization.getReturnTypeAndParameters()) {
- if (Utils.isObject(parameter.getType())) {
- continue;
- }
- Set types = new HashSet<>();
- for (SpecializationData specialization : specializations) {
- ActualParameter actualParameter = specialization.findParameter(parameter.getLocalName());
- if (actualParameter != null) {
- types.add(Utils.getQualifiedName(actualParameter.getType()));
- }
- }
- if (types.size() > 1) {
- genericSpecialization.replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, node.getTypeSystem().getGenericTypeData()));
- }
- }
- TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), null, null, genericSpecialization.getReturnType(),
- genericSpecialization.getParameters());
- // should not use messages from generic specialization
- uninializedMethod.getMessages().clear();
- specializations.add(new SpecializationData(uninializedMethod, false, true, false));
+ initializeGeneric(node);
+ initializeUninitialized(node);
+ initializePolymorphism(node); // requires specializations
+ Collections.sort(node.getSpecializations());
+ initializeReachability(node);
+
+ // reduce polymorphicness if generic is not reachable
+ if (node.getGenericSpecialization() != null && !node.getGenericSpecialization().isReachable()) {
+ node.setPolymorphicDepth(1);
+ node.getSpecializations().remove(node.getPolymorphicSpecialization());
}
- Collections.sort(specializations);
-
- node.setSpecializations(specializations);
-
List needsId = new ArrayList<>();
- for (SpecializationData specialization : specializations) {
+ for (SpecializationData specialization : node.getSpecializations()) {
if (specialization.isGeneric()) {
specialization.setId("Generic");
} else if (specialization.isUninitialized()) {
specialization.setId("Uninitialized");
+ } else if (specialization.isPolymorphic()) {
+ specialization.setId("Polymorphic");
+ } else if (specialization.isSpecialized()) {
+ needsId.add(specialization);
} else {
- needsId.add(specialization);
+ throw new AssertionError();
}
}
// verify specialization parameter length
- if (verifySpecializationParameters(node)) {
- List ids = calculateSpecializationIds(needsId);
- for (int i = 0; i < ids.size(); i++) {
- needsId.get(i).setId(ids.get(i));
- }
+ List ids = initializeSpecializationIds(needsId);
+ for (int i = 0; i < ids.size(); i++) {
+ needsId.get(i).setId(ids.get(i));
}
- // calculate reachability
+ }
+
+ private void initializeReachability(final NodeData node) {
SpecializationData prev = null;
- int polymorphicCombinations = 0;
boolean reachable = true;
- for (SpecializationData specialization : specializations) {
- if (specialization.isUninitialized()) {
+ for (SpecializationData specialization : node.getSpecializations()) {
+ if (specialization.isUninitialized() || specialization.isPolymorphic()) {
specialization.setReachable(true);
continue;
}
@@ -700,204 +589,21 @@
if (!specialization.hasRewrite(context)) {
reachable = false;
}
- if (!specialization.isGeneric()) {
- int combinations = 1;
- for (ActualParameter parameter : specialization.getParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- continue;
- }
- TypeData type = parameter.getTypeSystemType();
- combinations *= node.getTypeSystem().lookupSourceTypes(type).size();
- }
- polymorphicCombinations += combinations;
- }
-
prev = specialization;
}
-
- // initialize polymorphic depth
- if (node.getPolymorphicDepth() < 0) {
- node.setPolymorphicDepth(polymorphicCombinations - 1);
- }
-
- // reduce polymorphicness if generic is not reachable
- if (node.getGenericSpecialization() != null && !node.getGenericSpecialization().isReachable()) {
- node.setPolymorphicDepth(1);
- }
}
- private SpecializationData createGenericSpecialization(final NodeData node, List specializations) {
- SpecializationData genericSpecialization;
- SpecializationData specialization = specializations.get(0);
- GenericParser parser = new GenericParser(context, node);
- MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null);
-
- List parameters = new ArrayList<>();
- for (ActualParameter parameter : specialization.getReturnTypeAndParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- parameters.add(new ActualParameter(parameter));
- continue;
- }
- NodeData childNode = node;
- NodeChildData child = node.findChild(parameter.getSpecification().getName());
- if (child != null) {
- childNode = child.getNodeData();
- }
-
- TypeData genericType = null;
-
- Set types = new HashSet<>();
- for (SpecializationData otherSpecialization : specializations) {
- ActualParameter otherParameter = otherSpecialization.findParameter(parameter.getLocalName());
- if (otherParameter != null) {
- types.add(otherParameter.getTypeSystemType());
- }
- }
-
- assert !types.isEmpty();
-
- if (types.size() == 1) {
- ExecutableTypeData executable = childNode.findExecutableType(types.iterator().next(), 0);
- if (executable != null && !executable.hasUnexpectedValue(context)) {
- genericType = types.iterator().next();
- } else {
- genericType = childNode.findAnyGenericExecutableType(context, 0).getType();
- }
- } else {
- genericType = childNode.findAnyGenericExecutableType(context, 0).getType();
- }
-
- parameters.add(new ActualParameter(parameter, genericType));
- }
- ActualParameter returnType = parameters.get(0);
- parameters = parameters.subList(1, parameters.size());
-
- TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
- genericSpecialization = new SpecializationData(genericMethod, true, false, false);
- return genericSpecialization;
- }
-
- private void assignShortCircuitsToSpecializations(NodeData node) {
- Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits());
-
- boolean valid = true;
- for (NodeChildData field : node.filterFields(ExecutionKind.SHORT_CIRCUIT)) {
- String valueName = field.getName();
- 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(node, 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;
- }
-
- NodeChildData[] fields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
- List specializations = new ArrayList<>();
- specializations.addAll(node.getSpecializations());
- specializations.addAll(node.getPolymorphicSpecializations());
-
- for (SpecializationData specialization : specializations) {
- List assignedShortCuts = new ArrayList<>(fields.length);
-
- for (int i = 0; i < fields.length; i++) {
- List availableShortCuts = groupedShortCircuits.get(fields[i].getName());
-
- 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 void matchGuards(List elements, SpecializationData specialization) {
- if (specialization.getGuardDefinitions().isEmpty()) {
- specialization.setGuards(Collections. emptyList());
- return;
- }
-
- List foundGuards = new ArrayList<>();
- List methods = ElementFilter.methodsIn(elements);
- for (String guardDefinition : specialization.getGuardDefinitions()) {
- GuardParser parser = new GuardParser(context, specialization, guardDefinition);
- List guards = parser.parse(methods);
- if (!guards.isEmpty()) {
- foundGuards.add(guards.get(0));
- } else {
- // error no guard found
- MethodSpec spec = parser.createSpecification(specialization.getMethod(), null);
- spec.applyTypeDefinitions("types");
- specialization.addError("Guard with method name '%s' not found. Expected signature: %n%s", guardDefinition, spec.toSignatureString("guard"));
- }
- }
-
- specialization.setGuards(foundGuards);
-
- }
-
- private static List calculateSpecializationIds(List specializations) {
+ private static List initializeSpecializationIds(List specializations) {
int lastSize = -1;
List> signatureChunks = new ArrayList<>();
for (SpecializationData other : specializations) {
- if (other.isUninitialized() || other.isGeneric()) {
+ if (!other.isSpecialized()) {
continue;
}
List paramIds = new LinkedList<>();
paramIds.add(Utils.getTypeId(other.getReturnType().getType()));
for (ActualParameter param : other.getParameters()) {
- if (other.getNode().findChild(param.getSpecification().getName()) == null) {
+ if (param.getSpecification().getExecution() == null) {
continue;
}
paramIds.add(Utils.getTypeId(param.getType()));
@@ -999,25 +705,370 @@
return signatures;
}
- private void verifyNode(NodeData nodeData, List extends Element> elements) {
- // verify order is not ambiguous
- verifySpecializationOrder(nodeData);
+ private void initializeGuards(List extends Element> elements, SpecializationData specialization) {
+ if (specialization.getGuardDefinitions().isEmpty()) {
+ specialization.setGuards(Collections. emptyList());
+ return;
+ }
+
+ List foundGuards = new ArrayList<>();
+ List methods = ElementFilter.methodsIn(elements);
+ for (String guardDefinition : specialization.getGuardDefinitions()) {
+ GuardParser parser = new GuardParser(context, specialization, guardDefinition);
+ List guards = parser.parse(methods);
+ if (!guards.isEmpty()) {
+ foundGuards.add(guards.get(0));
+ } else {
+ // error no guard found
+ MethodSpec spec = parser.createSpecification(specialization.getMethod(), null);
+ spec.applyTypeDefinitions("types");
+ specialization.addError("Guard with method name '%s' not found. Expected signature: %n%s", guardDefinition, spec.toSignatureString("guard"));
+ }
+ }
+
+ specialization.setGuards(foundGuards);
+
+ }
+
+ private void initializeGeneric(final NodeData node) {
+ if (!node.needsRewrites(context)) {
+ return;
+ }
- verifyMissingAbstractMethods(nodeData, elements);
+ List generics = new ArrayList<>();
+ for (SpecializationData spec : node.getSpecializations()) {
+ if (spec.isGeneric()) {
+ 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.", Generic.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 @%s is allowed per operation.", Generic.class.getSimpleName());
+ }
+ }
+ }
+ }
+
+ private SpecializationData createGenericSpecialization(final NodeData node) {
+ SpecializationData specialization = node.getSpecializations().get(0);
+ GenericParser parser = new GenericParser(context, node);
+ MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null);
+ specification.getImplicitRequiredTypes().clear();
+
+ List parameterTypes = new ArrayList<>();
+ int signatureIndex = 1;
+ for (ParameterSpec spec : specification.getRequired()) {
+ parameterTypes.add(createGenericType(spec, node.getSpecializations(), signatureIndex));
+ if (spec.isSignature()) {
+ signatureIndex++;
+ }
+ }
+ TypeMirror returnType = createGenericType(specification.getReturnType(), node.getSpecializations(), 0);
+ return parser.create("Generic", null, null, returnType, parameterTypes);
+ }
- verifyConstructors(nodeData);
+ private TypeMirror createGenericType(ParameterSpec spec, List specializations, int signatureIndex) {
+ NodeExecutionData execution = spec.getExecution();
+ if (execution == null) {
+ if (spec.getAllowedTypes().size() == 1) {
+ return spec.getAllowedTypes().get(0);
+ } else {
+ return Utils.getCommonSuperType(context, spec.getAllowedTypes().toArray(new TypeMirror[0]));
+ }
+ } else {
+ Set types = new HashSet<>();
+ for (SpecializationData specialization : specializations) {
+ types.add(specialization.getTypeSignature().get(signatureIndex));
+ }
+
+ NodeChildData child = execution.getChild();
+
+ TypeData genericType = null;
+ if (types.size() == 1) {
+ ExecutableTypeData executable = child.findExecutableType(context, types.iterator().next());
+ if (executable != null && !executable.hasUnexpectedValue(context)) {
+ genericType = types.iterator().next();
+ }
+ }
+ if (genericType == null) {
+ genericType = child.findAnyGenericExecutableType(context).getType();
+ }
+ return genericType.getPrimitiveType();
+ }
+ }
- verifyNamingConvention(nodeData.getShortCircuits(), "needs");
+ private static void initializeUninitialized(final NodeData node) {
+ SpecializationData generic = node.getGenericSpecialization();
+ if (generic == null) {
+ return;
+ }
+ for (ActualParameter parameter : generic.getReturnTypeAndParameters()) {
+ if (Utils.isObject(parameter.getType())) {
+ continue;
+ }
+ Set types = new HashSet<>();
+ for (SpecializationData specialization : node.getSpecializations()) {
+ ActualParameter actualParameter = specialization.findParameter(parameter.getLocalName());
+ if (actualParameter != null) {
+ types.add(Utils.getQualifiedName(actualParameter.getType()));
+ }
+ }
+ if (types.size() > 1) {
+ generic.replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, node.getTypeSystem().getGenericTypeData()));
+ }
+ }
+ TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", 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) {
+ initializePolymorphicDepth(node);
+
+ if (!node.needsRewrites(context) || !node.isPolymorphic()) {
+ return;
+ }
- verifySpecializationThrows(nodeData);
+ SpecializationData generic = node.getGenericSpecialization();
+
+ List polymorphicSignature = new ArrayList<>();
+ List updatePolymorphic = Arrays.asList();
+ for (ActualParameter genericParameter : updatePolymorphic) {
+ if (!genericParameter.getSpecification().isSignature()) {
+ continue;
+ }
+
+ Set usedTypes = new HashSet<>();
+ for (SpecializationData specialization : node.getSpecializations()) {
+ if (!specialization.isSpecialized()) {
+ continue;
+ }
+ ActualParameter parameter = specialization.findParameter(genericParameter.getLocalName());
+ if (parameter == null) {
+ throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName());
+ }
+ usedTypes.add(parameter.getTypeSystemType());
+ }
+
+ TypeData polymorphicType;
+ if (usedTypes.size() == 1) {
+ polymorphicType = usedTypes.iterator().next();
+ } else {
+ polymorphicType = node.getTypeSystem().getGenericTypeData();
+ }
+ polymorphicSignature.add(polymorphicType);
+ }
+
+ SpecializationData polymorphic = new SpecializationData(node, generic, SpecializationKind.POLYMORPHIC);
+ polymorphic.updateSignature(new TypeSignature(polymorphicSignature));
+ node.getSpecializations().add(polymorphic);
}
- private static void verifyNodeChild(NodeChildData nodeChild) {
- if (nodeChild.getNodeType() == null) {
- nodeChild.addError("No valid node type could be resoleved.");
+ private static void initializePolymorphicDepth(final NodeData node) {
+ int polymorphicCombinations = 0;
+ for (SpecializationData specialization : node.getSpecializations()) {
+ if (specialization.isGeneric()) {
+ continue;
+ }
+
+ int combinations = 1;
+ for (ActualParameter parameter : specialization.getSignatureParameters()) {
+ combinations *= node.getTypeSystem().lookupSourceTypes(parameter.getTypeSystemType()).size();
+ }
+ polymorphicCombinations += combinations;
+ }
+
+ // initialize polymorphic depth
+ if (node.getPolymorphicDepth() < 0) {
+ node.setPolymorphicDepth(polymorphicCombinations - 1);
+ }
+
+ }
+
+ 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.getShortCircuitId();
+ 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;
}
- // FIXME verify node child
- // FIXME verify node type set
+
+ 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.getShortCircuitId());
+
+ 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 (ActualParameter 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 (executable.getType().equalsType(parameter.getTypeSystemType())) {
+ 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 verifySpecializationOrder(NodeData node) {
+ List specializations = node.getSpecializations();
+ for (int i = 0; i < specializations.size(); i++) {
+ SpecializationData m1 = specializations.get(i);
+ for (int j = i + 1; j < specializations.size(); j++) {
+ SpecializationData m2 = specializations.get(j);
+ int inferredOrder = m1.compareBySignature(m2);
+
+ if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
+ int specOrder = m1.getOrder() - m2.getOrder();
+ if (specOrder == 0) {
+ m1.addError("Order value %d used multiple times", m1.getOrder());
+ m2.addError("Order value %d used multiple times", m1.getOrder());
+ return;
+ } else if ((specOrder < 0 && inferredOrder > 0) || (specOrder > 0 && inferredOrder < 0)) {
+ m1.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
+ m2.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
+ return;
+ }
+ } else if (inferredOrder == 0) {
+ SpecializationData m = (m1.getOrder() == Specialization.DEFAULT_ORDER ? m1 : m2);
+ m.addError("Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
+ return;
+ }
+ }
+ }
}
private static void verifyMissingAbstractMethods(NodeData nodeData, List extends Element> originalElements) {
@@ -1028,7 +1079,6 @@
}
List elements = new ArrayList<>(originalElements);
-
Set unusedElements = new HashSet<>(elements);
for (TemplateMethod method : nodeData.getAllTemplateMethods()) {
unusedElements.remove(method.getMethod());
@@ -1053,6 +1103,33 @@
}
}
+ private static void verifyNamingConvention(List extends TemplateMethod> 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 && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
+ throwsData.addError("Duplicate exception type.");
+ }
+ }
+ }
+ }
+ }
+ }
+
private void verifyConstructors(NodeData nodeData) {
if (!nodeData.needsRewrites(context)) {
// no specialization constructor is needed if the node never rewrites.
@@ -1093,104 +1170,6 @@
return constructor.getParameters().size() == 1 && Utils.typeEquals(constructor.getParameters().get(0).asType(), context.getTruffleTypes().getSourceSection());
}
- private static boolean verifySpecializationParameters(NodeData nodeData) {
- boolean valid = true;
- int args = -1;
- for (SpecializationData specializationData : nodeData.getSpecializations()) {
- int signatureArgs = 0;
- for (ActualParameter param : specializationData.getParameters()) {
- if (param.getSpecification().isSignature()) {
- signatureArgs++;
- }
- }
- if (args != -1 && args != signatureArgs) {
- valid = false;
- break;
- }
- args = signatureArgs;
- }
- if (!valid) {
- for (SpecializationData specialization : nodeData.getSpecializations()) {
- specialization.addError("All specializations must have the same number of arguments.");
- }
- }
- return valid;
- }
-
- private static void verifySpecializationOrder(NodeData node) {
- List specializations = node.getSpecializations();
- for (int i = 0; i < specializations.size(); i++) {
- SpecializationData m1 = specializations.get(i);
- for (int j = i + 1; j < specializations.size(); j++) {
- SpecializationData m2 = specializations.get(j);
- int inferredOrder = m1.compareBySignature(m2);
-
- if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
- int specOrder = m1.getOrder() - m2.getOrder();
- if (specOrder == 0) {
- m1.addError("Order value %d used multiple times", m1.getOrder());
- m2.addError("Order value %d used multiple times", m1.getOrder());
- return;
- } else if ((specOrder < 0 && inferredOrder > 0) || (specOrder > 0 && inferredOrder < 0)) {
- m1.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
- m2.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
- return;
- }
- } else if (inferredOrder == 0) {
- SpecializationData m = (m1.getOrder() == Specialization.DEFAULT_ORDER ? m1 : m2);
- m.addError("Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
- return;
- }
- }
- }
- }
-
- 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 && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
- throwsData.addError("Duplicate exception type.");
- }
- }
- }
- }
- }
- }
-
- private static void verifyNamingConvention(List extends TemplateMethod> 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 Map> groupExecutableTypes(List executableTypes) {
- Map> groupedTypes = new TreeMap<>();
- for (ExecutableTypeData type : executableTypes) {
- int evaluatedCount = type.getEvaluatedCount();
-
- List types = groupedTypes.get(evaluatedCount);
- if (types == null) {
- types = new ArrayList<>();
- groupedTypes.put(evaluatedCount, types);
- }
- types.add(type);
- }
-
- for (List types : groupedTypes.values()) {
- Collections.sort(types);
- }
- return groupedTypes;
- }
-
private AnnotationMirror findFirstAnnotation(List extends Element> elements, Class extends Annotation> annotation) {
for (Element element : elements) {
AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, element, annotation);
@@ -1230,61 +1209,13 @@
return null;
}
- private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
- for (ActualParameter parameter : method.getParameters()) {
- NodeChildData field = node.findChild(parameter.getSpecification().getName());
- if (field == null) {
- continue;
- }
- ExecutableTypeData found = null;
- List executableElements = field.findGenericExecutableTypes(context);
- for (ExecutableTypeData executable : executableElements) {
- if (executable.getType().equalsType(parameter.getTypeSystemType())) {
- found = executable;
- break;
- }
- }
- if (found == null) {
- return false;
+ private static List collectSuperClasses(List collection, TypeElement element) {
+ if (element != null) {
+ collection.add(element);
+ if (element.getSuperclass() != null) {
+ collectSuperClasses(collection, Utils.fromTypeMirror(element.getSuperclass()));
}
}
- 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 SortedMap> groupByNodeId(List methods) {
- SortedMap> grouped = new TreeMap<>();
- for (M m : methods) {
- List list = grouped.get(m.getId());
- if (list == null) {
- list = new ArrayList<>();
- grouped.put(m.getId(), list);
- }
- list.add(m);
- }
- return grouped;
- }
-
- private static List findSuperClasses(List collection, TypeElement element) {
- if (element.getSuperclass() != null) {
- TypeElement superElement = Utils.fromTypeMirror(element.getSuperclass());
- if (superElement != null) {
- findSuperClasses(collection, superElement);
- }
- }
- collection.add(element);
return collection;
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -29,7 +29,6 @@
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
import com.oracle.truffle.dsl.processor.template.*;
public class ShortCircuitParser extends NodeMethodParser {
@@ -40,15 +39,17 @@
super(context, node);
shortCircuitValues = new HashSet<>();
- NodeChildData[] shortCircuitFields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
- for (NodeChildData field : shortCircuitFields) {
- shortCircuitValues.add(field.getName());
+ for (NodeExecutionData execution : node.getChildExecutions()) {
+ if (execution.isShortCircuit()) {
+ shortCircuitValues.add(execution.getShortCircuitId());
+ }
}
}
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
+
return createDefaultMethodSpec(method, mirror, true, shortCircuitValue);
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Tue Jan 07 18:53:04 2014 +0100
@@ -33,24 +33,25 @@
public class SpecializationData extends TemplateMethod {
+ public enum SpecializationKind {
+ UNINITIALIZED, SPECIALIZED, POLYMORPHIC, GENERIC
+ }
+
+ private final NodeData node;
private final int order;
- private final boolean generic;
- private final boolean polymorphic;
- private final boolean uninitialized;
+ private final SpecializationKind kind;
private final List exceptions;
private List guardDefinitions = Collections.emptyList();
private List guards = Collections.emptyList();
private List shortCircuits;
private List assumptions = Collections.emptyList();
- private NodeData node;
private boolean reachable;
- public SpecializationData(TemplateMethod template, int order, List exceptions) {
+ public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, int order, List exceptions) {
super(template);
+ this.node = node;
this.order = order;
- this.generic = false;
- this.uninitialized = false;
- this.polymorphic = false;
+ this.kind = kind;
this.exceptions = exceptions;
for (SpecializationThrowsData exception : exceptions) {
@@ -58,13 +59,8 @@
}
}
- public SpecializationData(TemplateMethod template, boolean generic, boolean uninitialized, boolean polymorphic) {
- super(template);
- this.order = Specialization.DEFAULT_ORDER;
- this.generic = generic;
- this.uninitialized = uninitialized;
- this.polymorphic = polymorphic;
- this.exceptions = Collections.emptyList();
+ public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) {
+ this(node, template, kind, Specialization.DEFAULT_ORDER, new ArrayList());
}
public void setReachable(boolean reachable) {
@@ -76,7 +72,7 @@
}
public boolean isPolymorphic() {
- return polymorphic;
+ return kind == SpecializationKind.POLYMORPHIC;
}
@Override
@@ -99,20 +95,12 @@
return false;
}
- for (ActualParameter parameter : getParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- continue;
- }
- NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
- if (child == null) {
- continue;
- }
+ for (ActualParameter parameter : getSignatureParameters()) {
ActualParameter genericParameter = getNode().getGenericSpecialization().findParameter(parameter.getLocalName());
if (!parameter.getTypeSystemType().equals(genericParameter.getTypeSystemType())) {
return false;
}
}
-
return true;
}
@@ -126,12 +114,8 @@
if (!getAssumptions().isEmpty()) {
return true;
}
- for (ActualParameter parameter : getParameters()) {
- NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
- if (child == null) {
- continue;
- }
- ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType());
+ for (ActualParameter parameter : getSignatureParameters()) {
+ ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType());
if (type.hasUnexpectedValue(context)) {
return true;
}
@@ -153,12 +137,12 @@
SpecializationData m2 = (SpecializationData) other;
+ int kindOrder = kind.compareTo(m2.kind);
+ if (kindOrder != 0) {
+ return kindOrder;
+ }
if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
return getOrder() - m2.getOrder();
- } else if (isUninitialized() ^ m2.isUninitialized()) {
- return isUninitialized() ? -1 : 1;
- } else if (isGeneric() ^ m2.isGeneric()) {
- return isGeneric() ? 1 : -1;
}
if (getTemplate() != m2.getTemplate()) {
@@ -172,10 +156,6 @@
return node;
}
- public void setNode(NodeData node) {
- this.node = node;
- }
-
public void setGuards(List guards) {
this.guards = guards;
}
@@ -189,15 +169,15 @@
}
public boolean isSpecialized() {
- return !isGeneric() && !isUninitialized() && !isPolymorphic();
+ return kind == SpecializationKind.SPECIALIZED;
}
public boolean isGeneric() {
- return generic;
+ return kind == SpecializationKind.GENERIC;
}
public boolean isUninitialized() {
- return uninitialized;
+ return kind == SpecializationKind.UNINITIALIZED;
}
public List getExceptions() {
@@ -254,7 +234,7 @@
@Override
public String toString() {
- return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature());
+ return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature());
}
public void forceFrame(TypeMirror frameType) {
@@ -267,7 +247,7 @@
}
public boolean equalsGuards(SpecializationData specialization) {
- if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getSignature().equalsParameters(specialization.getSignature())) {
+ if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getTypeSignature().equalsParameters(specialization.getTypeSignature())) {
return true;
}
return false;
@@ -281,4 +261,5 @@
}
return false;
}
+
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Jan 07 18:53:04 2014 +0100
@@ -28,7 +28,7 @@
import com.oracle.truffle.dsl.processor.*;
import com.oracle.truffle.dsl.processor.template.*;
-import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature;
+import com.oracle.truffle.dsl.processor.template.TemplateMethod.TypeSignature;
import com.oracle.truffle.dsl.processor.typesystem.*;
/**
@@ -55,7 +55,7 @@
this.specialization = data;
this.assumptions.addAll(data.getAssumptions());
- Signature sig = data.getSignature();
+ TypeSignature sig = data.getTypeSignature();
for (int i = 1; i < sig.size(); i++) {
typeGuards.add(new TypeGuard(sig.get(i), i - 1));
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java Tue Jan 07 14:41:52 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.node;
-
-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.template.*;
-
-public class SpecializationListenerParser extends NodeMethodParser {
-
- public SpecializationListenerParser(ProcessorContext context, NodeData node) {
- super(context, node);
- }
-
- @Override
- public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- return createDefaultMethodSpec(method, mirror, true, null);
- }
-
- @Override
- protected ParameterSpec createReturnParameterSpec() {
- return new ParameterSpec("void", getContext().getType(void.class));
- }
-
- @Override
- public SpecializationListenerData create(TemplateMethod method, boolean invalid) {
- return new SpecializationListenerData(method);
- }
-
- @Override
- public Class extends Annotation> getAnnotationType() {
- return SpecializationListener.class;
- }
-
-}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java Tue Jan 07 18:53:04 2014 +0100
@@ -30,6 +30,7 @@
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.SpecializationData.SpecializationKind;
import com.oracle.truffle.dsl.processor.template.*;
public class SpecializationMethodParser extends NodeMethodParser {
@@ -77,7 +78,7 @@
return Utils.compareByTypeHierarchy(o1.getJavaClass(), o2.getJavaClass());
}
});
- SpecializationData specialization = new SpecializationData(method, order, exceptionData);
+ SpecializationData specialization = new SpecializationData(getNode(), method, SpecializationKind.SPECIALIZED, order, exceptionData);
List guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
specialization.setGuardDefinitions(guardDefs);
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Tue Jan 07 18:53:04 2014 +0100
@@ -33,24 +33,24 @@
private TypeData typeSystemType;
private TemplateMethod method;
private final String localName;
- private final int specificationIndex;
- private final int varArgsIndex;
+ private final int specificationVarArgsIndex;
+ private final int typeVarArgsIndex;
private final boolean implicit;
- private final TypeMirror type;
+ private final TypeMirror actualType;
- public ActualParameter(ParameterSpec specification, TypeMirror actualType, int specificationIndex, int varArgsIndex, boolean implicit) {
+ public ActualParameter(ParameterSpec specification, TypeMirror actualType, int specificationVarArgsIndex, int typeVarArgsIndex, boolean implicit) {
this.specification = specification;
- this.type = actualType;
+ this.actualType = actualType;
this.typeSystemType = null;
- this.specificationIndex = specificationIndex;
+ this.specificationVarArgsIndex = specificationVarArgsIndex;
this.implicit = implicit;
- String valueName = specification.getName() + "Value";
- if (specification.isIndexed()) {
- valueName += specificationIndex;
+ String valueName = specification.getName() + "Value";
+ if (specificationVarArgsIndex > -1) {
+ valueName += "_" + specificationVarArgsIndex;
}
- this.varArgsIndex = varArgsIndex;
+ this.typeVarArgsIndex = typeVarArgsIndex;
this.localName = valueName;
}
@@ -60,29 +60,29 @@
}
public ActualParameter(ActualParameter parameter, TypeData otherType) {
- this(parameter.specification, otherType, parameter.specificationIndex, parameter.varArgsIndex, parameter.implicit);
+ this(parameter.specification, otherType, parameter.specificationVarArgsIndex, parameter.typeVarArgsIndex, parameter.implicit);
}
public ActualParameter(ActualParameter parameter) {
this.specification = parameter.specification;
- this.type = parameter.type;
+ this.actualType = parameter.actualType;
this.typeSystemType = parameter.typeSystemType;
- this.specificationIndex = parameter.specificationIndex;
+ this.specificationVarArgsIndex = parameter.specificationVarArgsIndex;
this.implicit = parameter.implicit;
this.localName = parameter.localName;
- this.varArgsIndex = parameter.varArgsIndex;
+ this.typeVarArgsIndex = parameter.typeVarArgsIndex;
}
- public int getVarArgsIndex() {
- return varArgsIndex;
+ public int getTypeVarArgsIndex() {
+ return typeVarArgsIndex;
}
public boolean isImplicit() {
return implicit;
}
- public int getSpecificationIndex() {
- return specificationIndex;
+ public int getSpecificationVarArgsIndex() {
+ return specificationVarArgsIndex;
}
public String getLocalName() {
@@ -102,15 +102,15 @@
}
public TypeMirror getType() {
- return type;
+ return actualType;
}
public TypeData getTypeSystemType() {
return typeSystemType;
}
- public boolean isVarArgs() {
- return varArgsIndex >= 0;
+ public boolean isTypeVarArgs() {
+ return typeVarArgsIndex >= 0;
}
public ActualParameter getPreviousParameter() {
@@ -119,6 +119,6 @@
@Override
public String toString() {
- return Utils.getSimpleName(type);
+ return Utils.getSimpleName(actualType);
}
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Tue Jan 07 18:53:04 2014 +0100
@@ -64,8 +64,8 @@
}
verifyExpectedMessages(context, log, childMessages);
- for (Message message : getMessages()) {
- emitDefault(context, baseElement, log, message);
+ for (int i = getMessages().size() - 1; i >= 0; i--) {
+ emitDefault(context, baseElement, log, getMessages().get(i));
}
for (MessageContainer sink : findChildContainers()) {
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Tue Jan 07 18:53:04 2014 +0100
@@ -27,7 +27,6 @@
import javax.lang.model.type.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
public class MethodSpec {
@@ -37,34 +36,36 @@
private final List optional = new ArrayList<>();
private final List required = new ArrayList<>();
- private int minimumRequiredArguments;
- private boolean variableRequiredArguments;
+ private boolean ignoreAdditionalParameters;
+ private boolean ignoreAdditionalSpecifications;
+ private boolean variableRequiredParameters;
+
private List typeDefinitions;
public MethodSpec(ParameterSpec returnType) {
this.returnType = returnType;
}
- public void setMinimumRequiredArguments(int minimumRequiredArguments) {
- this.minimumRequiredArguments = minimumRequiredArguments;
+ public void setVariableRequiredParameters(boolean variableRequiredParameters) {
+ this.variableRequiredParameters = variableRequiredParameters;
}
- public int getMinimumRequiredArguments() {
- return minimumRequiredArguments;
- }
-
- public void setVariableRequiredArguments(boolean variableArguments) {
- this.variableRequiredArguments = variableArguments;
- }
-
- public boolean isVariableRequiredArguments() {
- return variableRequiredArguments;
+ public boolean isVariableRequiredParameters() {
+ return variableRequiredParameters;
}
public void addImplicitRequiredType(TypeMirror type) {
this.implicitRequiredTypes.add(type);
}
+ public void setIgnoreAdditionalParameters(boolean ignoreAdditionalParameter) {
+ this.ignoreAdditionalParameters = ignoreAdditionalParameter;
+ }
+
+ public boolean isIgnoreAdditionalParameters() {
+ return ignoreAdditionalParameters;
+ }
+
public void addOptional(ParameterSpec spec) {
optional.add(spec);
}
@@ -158,15 +159,18 @@
sep = ", ";
}
- for (ParameterSpec requiredSpec : getRequired()) {
+ for (int i = 0; i < getRequired().size(); i++) {
+ ParameterSpec requiredSpec = getRequired().get(i);
b.append(sep);
- if (requiredSpec.getCardinality() == Cardinality.MANY) {
- b.append("{");
+
+ if (isVariableRequiredParameters() && i == getRequired().size() - 1) {
+ b.append(("{"));
}
b.append(createTypeSignature(requiredSpec, false));
- if (requiredSpec.getCardinality() == Cardinality.MANY) {
- b.append("}");
+ if (isVariableRequiredParameters() && i == getRequired().size() - 1) {
+ b.append(("}"));
}
+
sep = ", ";
}
@@ -234,4 +238,12 @@
}
}
+ public void setIgnoreAdditionalSpecifications(boolean ignoreAdditoinalSpecifications) {
+ this.ignoreAdditionalSpecifications = ignoreAdditoinalSpecifications;
+ }
+
+ public boolean isIgnoreAdditionalSpecifications() {
+ return ignoreAdditionalSpecifications;
+ }
+
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java Tue Jan 07 18:53:04 2014 +0100
@@ -27,44 +27,46 @@
import javax.lang.model.type.*;
import com.oracle.truffle.dsl.processor.*;
-import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
-import com.oracle.truffle.dsl.processor.template.MethodSpec.*;
+import com.oracle.truffle.dsl.processor.node.*;
+import com.oracle.truffle.dsl.processor.template.MethodSpec.TypeDef;
public class ParameterSpec {
private final String name;
private final List allowedTypes;
- /** Cardinality one or multiple. */
- private Cardinality cardinality = Cardinality.ONE;
- /** Type is part of the method signature. Relevant for comparisons. */
- private boolean signature;
- /** Type must be indexed when parsing. */
- private boolean indexed;
/** Type is bound to local final variable. */
private boolean local;
+ /** Optional bound execution of node. */
+ private NodeExecutionData execution;
private TypeDef typeDefinition;
- public ParameterSpec(String name, TypeMirror... allowedTypes) {
- this(name, Arrays.asList(allowedTypes));
- }
-
public ParameterSpec(String name, List allowedTypes) {
this.name = name;
this.allowedTypes = allowedTypes;
}
+ public ParameterSpec(String name, TypeMirror type) {
+ this(name, Arrays.asList(type));
+ }
+
public ParameterSpec(ParameterSpec o, List allowedTypes) {
this.name = o.name;
- this.cardinality = o.cardinality;
- this.signature = o.signature;
- this.indexed = o.indexed;
this.local = o.local;
this.typeDefinition = o.typeDefinition;
+ this.execution = o.execution;
this.allowedTypes = allowedTypes;
}
+ public NodeExecutionData getExecution() {
+ return execution;
+ }
+
+ public void setExecution(NodeExecutionData executionData) {
+ this.execution = executionData;
+ }
+
void setTypeDefinition(TypeDef typeDefinition) {
this.typeDefinition = typeDefinition;
}
@@ -73,42 +75,22 @@
return typeDefinition;
}
- public void setSignature(boolean signature) {
- this.signature = signature;
- }
-
public void setLocal(boolean local) {
this.local = local;
}
public boolean isSignature() {
- return signature;
+ return execution != null;
}
public boolean isLocal() {
return local;
}
- public boolean isIndexed() {
- return indexed;
- }
-
- public void setIndexed(boolean indexed) {
- this.indexed = indexed;
- }
-
- public void setCardinality(Cardinality cardinality) {
- this.cardinality = cardinality;
- }
-
public String getName() {
return name;
}
- public Cardinality getCardinality() {
- return cardinality;
- }
-
public List getAllowedTypes() {
return allowedTypes;
}
diff -r 56452e07874f -r 856c2c294f84 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Tue Jan 07 14:41:52 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Tue Jan 07 18:53:04 2014 +0100
@@ -29,6 +29,7 @@
import com.oracle.truffle.dsl.processor.*;
import com.oracle.truffle.dsl.processor.typesystem.*;
+import com.oracle.truffle.dsl.processor.util.*;
/**
* Note: this class has a natural ordering that is inconsistent with equals.
@@ -133,6 +134,14 @@
return requiredParameters;
}
+ public Iterable getSignatureParameters() {
+ return new FilteredIterable<>(getParameters(), new Predicate() {
+ public boolean evaluate(ActualParameter value) {
+ return value.getSpecification().isSignature();
+ }
+ });
+ }
+
public List getParameters() {
return parameters;
}
@@ -202,23 +211,19 @@
return prev;
}
+ @SuppressWarnings("unused")
public int getSignatureSize() {
int signatureSize = 0;
- for (ActualParameter parameter : getParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- continue;
- }
+ for (ActualParameter parameter : getSignatureParameters()) {
signatureSize++;
}
return signatureSize;
}
- public Signature getSignature() {
- Signature signature = new Signature();
- for (ActualParameter parameter : getReturnTypeAndParameters()) {
- if (!parameter.getSpecification().isSignature()) {
- continue;
- }
+ public TypeSignature getTypeSignature() {
+ TypeSignature signature = new TypeSignature();
+ signature.types.add(getReturnType().getTypeSystemType());
+ for (ActualParameter parameter : getSignatureParameters()) {
TypeData typeData = parameter.getTypeSystemType();
if (typeData != null) {
signature.types.add(typeData);
@@ -241,7 +246,7 @@
return null;
}
- public void updateSignature(Signature signature) {
+ public void updateSignature(TypeSignature signature) {
// TODO(CH): fails in normal usage - output ok though
// assert signature.size() >= 1;
@@ -299,8 +304,8 @@
throw new IllegalStateException("Cannot compare two methods with different type systems.");
}
- List signature1 = getSignatureTypes(getReturnTypeAndParameters());
- List