# HG changeset patch
# User Christian Humer
# Date 1363201530 -3600
# Node ID d02ba214b7e675ede365e40f59bf1a9af0432e33
# Parent 141af6b3b72bb1024021a140e62339c23ac1ef6d# Parent 35267b295f74c8960620beb2f80304ecb816553d
Merge.
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryOperationTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryOperationTest.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.codegen.test;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
+
+public class BinaryOperationTest {
+
+ 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");
+ }
+
+ @NodeClass(BinaryNode.class)
+ abstract static class BinaryNode extends ValueNode {
+
+ @Child protected ValueNode leftNode;
+ @Child protected ValueNode rightNode;
+
+ public BinaryNode(ValueNode left, ValueNode right) {
+ this.leftNode = left;
+ this.rightNode = right;
+ }
+
+ public BinaryNode(BinaryNode prev) {
+ this(prev.leftNode, prev.rightNode);
+ }
+
+ @Specialization
+ int add(int left, int right) {
+ return left + right;
+ }
+
+ @Generic
+ int add(Object left, Object right) {
+ return convertInt(left) + convertInt(right);
+ }
+
+ @Specialization
+ int sub(int left, int right) {
+ return left + right;
+ }
+
+ @Generic
+ int sub(Object left, Object right) {
+ return convertInt(left) + convertInt(right);
+ }
+
+ }
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,159 @@
+/*
+ * 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.codegen.test;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
+
+public class RuntimeStringTest {
+
+ @Test
+ public void testSubstr() {
+ assertExecute(new RuntimeString("es"), "substr", new RuntimeString("test"), 1, 3);
+ }
+
+ @Test
+ public void testConcat() {
+ assertExecute(new RuntimeString("concatconcat"), "concat", new RuntimeString("concat"), new RuntimeString("concat"));
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testConcatFail() {
+ assertExecute(new RuntimeString("concatconcat"), "concat", new RuntimeString("concat"));
+ }
+
+ @Test
+ public void testFindMethodByMethodName() {
+ // TODO
+ }
+
+ private static void assertExecute(Object expectedResult, String name, Object... argumentsArray) {
+ ArgNode[] args = new ArgNode[argumentsArray.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = new ArgNode(argumentsArray, i);
+ }
+
+ BuiltinNode node = null;
+ for (NodeFactory nodeFactory : RuntimeStringTestFactory.getFactories()) {
+ GeneratedBy generated = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
+ Assert.assertNotNull(generated);
+ Assert.assertNotSame("", generated.methodName());
+ if (generated.methodName().equals(name)) {
+ node = nodeFactory.createNode((Object) args);
+ break;
+ }
+ }
+ Assert.assertNotNull("Node not found", node);
+ CallTarget target = Truffle.getRuntime().createCallTarget(new TestRootNode(node));
+ Assert.assertEquals(expectedResult, target.call());
+ }
+
+ static class ArgNode extends ValueNode {
+
+ final Object[] arguments;
+ final int index;
+
+ ArgNode(Object[] args, int index) {
+ this.arguments = args;
+ this.index = index;
+ }
+
+ @Override
+ Object execute() {
+ return arguments[index];
+ }
+
+ }
+
+ abstract static class BuiltinNode extends ValueNode {
+
+ @Children ArgNode[] parameters;
+
+ BuiltinNode(ArgNode[] parameters) {
+ this.parameters = adoptChildren(parameters);
+ }
+
+ BuiltinNode(BuiltinNode prev) {
+ this(prev.parameters);
+ }
+
+ }
+
+ @NodeClass(BuiltinNode.class)
+ static class RuntimeString {
+
+ private final String internal;
+
+ public RuntimeString(String internal) {
+ this.internal = internal;
+ }
+
+ @Specialization
+ static RuntimeString concat(RuntimeString s1, RuntimeString s2) {
+ return new RuntimeString(s1.internal + s2.internal);
+ }
+
+ @Specialization
+ RuntimeString substr(int beginIndex, int endIndex) {
+ return new RuntimeString(internal.substring(beginIndex, endIndex));
+ }
+
+ @Generic
+ RuntimeString substr(Object beginIndex, Object endIndex) {
+ return substr(convertInt(beginIndex), convertInt(endIndex));
+ }
+
+ 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 RuntimeString) {
+ return internal.equals(((RuntimeString) obj).internal);
+ }
+ return super.equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return internal.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return internal;
+ }
+
+ }
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,71 @@
+/*
+ * 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.codegen.test;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.RuntimeStringTest.RuntimeString;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public class TypeSystemTest {
+
+ @TypeSystem({int.class, RuntimeString.class})
+ static class SimpleTypes {
+ }
+
+ @TypeSystemReference(SimpleTypes.class)
+ abstract static class ValueNode extends Node {
+
+ int executeInt() throws UnexpectedResultException {
+ return SimpleTypesGen.SIMPLETYPES.expectInteger(execute());
+ }
+
+ RuntimeString executeString() {
+ return new RuntimeString(execute().toString());
+ }
+
+ @SuppressWarnings("static-method")
+ final long executeSpecial() {
+ return 42L;
+ }
+
+ abstract Object execute();
+
+ }
+
+ @TypeSystemReference(SimpleTypes.class)
+ static class TestRootNode extends RootNode {
+
+ @Child private ValueNode node;
+
+ public TestRootNode(ValueNode node) {
+ this.node = adoptChild(node);
+ }
+
+ @Override
+ public Object execute(VirtualFrame frame) {
+ return node.execute();
+ }
+ }
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+/**
+ * This package contains basic tests of the Truffle-Source-Code-Generation (short Codegen) API and serves at the same
+ * time as an introduction to the Codegen API for language implementors. Every test gives an example on how to use the construct explained in the class description.
+ *
+ *
+ * This API relies heavily on the concepts described in {@link com.oracle.truffle.api.test}. We assume that the
+ * reader is already familiarized with those concepts.
+ *
+ *
+ *
+ * TODO general description
+ *
+ *
+ *
+ * This introduction to Codegen contains items in the following recommended order:
+ *
+ * Prerequisites:
+ *
+ *
+ *
+ * What do I need to get started? {@link com.oracle.truffle.api.codegen.test.TypeSystemTest}
+ * How would you generate function nodes for runtime objects? {@link com.oracle.truffle.api.codegen.test.RuntimeStringTest}
+ *
+ *
+ *
+ */
+package com.oracle.truffle.api.codegen.test;
+
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java Wed Mar 13 20:05:30 2013 +0100
@@ -25,12 +25,14 @@
import java.lang.annotation.*;
/**
- * Marks a type to be generated by another class.
+ * Marks a type to be generated by another class or a method.
*/
-@Retention(RetentionPolicy.CLASS)
+@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface GeneratedBy {
Class> value();
+ String methodName() default "";
+
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GuardCheck.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GuardCheck.java Wed Mar 13 11:00:43 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +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.codegen;
-
-import java.lang.annotation.*;
-
-/**
- *
- *
- * @see SpecializationGuard
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface GuardCheck {
-
-}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.codegen;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeClass {
+
+ Class extends Node> value();
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java Wed Mar 13 20:05:30 2013 +0100
@@ -24,6 +24,8 @@
import java.util.*;
+import com.oracle.truffle.api.nodes.*;
+
/**
* Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate
* generated node classes without using reflection.
@@ -63,4 +65,10 @@
*/
List>> getNodeSignatures();
+ /**
+ * Returns a list of children that will be executed by the created node. This is useful for base
+ * nodes that can execute a variable amount of nodes.
+ */
+ List> getExecutionSignature();
+
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.codegen;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface NodeId {
+
+ String value();
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java Wed Mar 13 20:05:30 2013 +0100
@@ -32,8 +32,8 @@
int order() default DEFAULT_ORDER;
- SpecializationThrows[] exceptions() default {};
+ Class extends Throwable>[] rewriteOn() default {};
- SpecializationGuard[] guards() default {};
+ String[] guards() default {};
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationGuard.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationGuard.java Wed Mar 13 11:00:43 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- * Specifies the use of a guard for a specialization.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface SpecializationGuard {
-
- /**
- * Specifies the name of the guard method annotated by {@link GuardCheck} specified as method in
- * the {@link TypeSystem} class.
- */
- String methodName();
-
- /**
- * Determines if a guard check is invoked on specialization. Defaults to true.
- */
- boolean onSpecialization() default true;
-
- /**
- * Determines if a guard check is invoked on execution. Defaults to true.
- */
- boolean onExecution() default true;
-
-}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationThrows.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationThrows.java Wed Mar 13 11:00:43 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +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.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface SpecializationThrows {
-
- Class extends Throwable> javaClass();
-
- String transitionTo();
-}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Wed Mar 13 20:05:30 2013 +0100
@@ -28,8 +28,8 @@
*
* Annotates a type system class that represents type information for a node. Generates code for
* converting and managing types. Methods contained in the type system may be annotated with
- * {@link TypeCast}, {@link TypeCheck} or {@link GuardCheck}. These methods alter the default
- * behavior of the type system.
+ * {@link TypeCast} or {@link TypeCheck}. These methods alter the default behavior of the type
+ * system.
*
*
*
@@ -62,7 +62,6 @@
*
* @see TypeCast
* @see TypeCheck
- * @see GuardCheck
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -58,12 +58,22 @@
if (!context.getTruffleTypes().verify(context, element, mirror)) {
return null;
}
- return parse(element, mirror);
+ M model = parse(element, mirror);
+ if (model == null) {
+ return null;
+ }
+
+ model.emitMessages((TypeElement) element, log);
+ return filterErrorElements(model);
} finally {
this.roundEnv = null;
}
}
+ protected M filterErrorElements(M model) {
+ return model.hasErrors() ? null : model;
+ }
+
protected abstract M parse(Element element, AnnotationMirror mirror);
public abstract Class extends Annotation> getAnnotationType();
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java Wed Mar 13 20:05:30 2013 +0100
@@ -41,30 +41,6 @@
this.processingEnv = env;
}
- public void warning(Element element, String format, Object... args) {
- message(Kind.WARNING, element, null, null, format, args);
- }
-
- public void warning(Element element, AnnotationMirror mirror, String format, Object... args) {
- message(Kind.WARNING, element, mirror, null, format, args);
- }
-
- public void error(Element element, String format, Object... args) {
- message(Kind.ERROR, element, null, null, format, args);
- }
-
- public void error(String format, Object... args) {
- message(Kind.ERROR, null, null, null, format, args);
- }
-
- public void error(Element element, AnnotationMirror mirror, String format, Object... args) {
- message(Kind.ERROR, element, mirror, null, format, args);
- }
-
- public void error(Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
- message(Kind.ERROR, element, mirror, value, format, args);
- }
-
public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
AnnotationMirror usedMirror = mirror;
Element usedElement = element;
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java Wed Mar 13 20:05:30 2013 +0100
@@ -28,6 +28,7 @@
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
+import javax.tools.Diagnostic.*;
import com.oracle.truffle.codegen.processor.ProcessorContext.ProcessCallback;
import com.oracle.truffle.codegen.processor.node.*;
@@ -95,7 +96,7 @@
private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) {
String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e;
- generator.getContext().getLog().error(e, message + ": " + Utils.printException(t));
+ generator.getContext().getLog().message(Kind.ERROR, e, null, null, message + ": " + Utils.printException(t));
}
@SuppressWarnings("unchecked")
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Wed Mar 13 20:05:30 2013 +0100
@@ -26,6 +26,7 @@
import javax.lang.model.element.*;
import javax.lang.model.type.*;
+import javax.tools.Diagnostic.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.intrinsics.*;
@@ -66,7 +67,7 @@
}
for (String error : errors) {
- context.getLog().error(element, mirror, error);
+ context.getLog().message(Kind.ERROR, element, mirror, null, error);
}
return false;
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Wed Mar 13 20:05:30 2013 +0100
@@ -55,9 +55,17 @@
return boxedType;
}
+ public static List asTypeMirrors(List extends Element> elements) {
+ List types = new ArrayList<>(elements.size());
+ for (Element element : elements) {
+ types.add(element.asType());
+ }
+ return types;
+ }
+
public static List collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element,
Class extends Annotation> annotationClass) {
- List result = Utils.getAnnotationValueList(markerAnnotation, elementName);
+ List result = Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName);
AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass);
if (explicit != null) {
result.add(explicit);
@@ -167,6 +175,46 @@
return new LinkedHashSet<>(Arrays.asList(modifier));
}
+ public static String getTypeId(TypeMirror mirror) {
+ switch (mirror.getKind()) {
+ case BOOLEAN:
+ return "Boolean";
+ case BYTE:
+ return "Byte";
+ case CHAR:
+ return "Char";
+ case DOUBLE:
+ return "Double";
+ case FLOAT:
+ return "Float";
+ case SHORT:
+ return "Short";
+ case INT:
+ return "Int";
+ case LONG:
+ return "Long";
+ case DECLARED:
+ return ((DeclaredType) mirror).asElement().getSimpleName().toString();
+ case ARRAY:
+ return getTypeId(((ArrayType) mirror).getComponentType()) + "Array";
+ case VOID:
+ return "Void";
+ case WILDCARD:
+ StringBuilder b = new StringBuilder();
+ WildcardType type = (WildcardType) mirror;
+ if (type.getExtendsBound() != null) {
+ b.append("Extends").append(getTypeId(type.getExtendsBound()));
+ } else if (type.getSuperBound() != null) {
+ b.append("Super").append(getTypeId(type.getExtendsBound()));
+ }
+ return b.toString();
+ case TYPEVAR:
+ return "Any";
+ default:
+ throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
+ }
+ }
+
public static String getSimpleName(TypeElement element) {
return getSimpleName(element.asType());
}
@@ -428,29 +476,32 @@
}
@SuppressWarnings("unchecked")
- public static List getAnnotationValueList(AnnotationMirror mirror, String name) {
+ public static List getAnnotationValueList(Class expectedListType, AnnotationMirror mirror, String name) {
+ List extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name);
List result = new ArrayList<>();
- List extends AnnotationValue> values = (List extends AnnotationValue>) getAnnotationValue(mirror, name).getValue();
+
for (AnnotationValue value : values) {
- result.add((T) value.getValue());
+ result.add(resolveAnnotationValue(expectedListType, value));
}
return result;
}
- public static TypeMirror getAnnotationValueType(AnnotationMirror mirror, String name) {
- return (TypeMirror) getAnnotationValue(mirror, name).getValue();
+ public static T getAnnotationValue(Class expectedType, AnnotationMirror mirror, String name) {
+ return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name));
}
- public static TypeMirror getAnnotationValueTypeMirror(AnnotationMirror mirror, String name) {
- return (TypeMirror) getAnnotationValue(mirror, name).getValue();
- }
-
- public static String getAnnotationValueString(AnnotationMirror mirror, String name) {
- return (String) getAnnotationValue(mirror, name).getValue();
- }
-
- public static int getAnnotationValueInt(AnnotationMirror mirror, String name) {
- return (int) getAnnotationValue(mirror, name).getValue();
+ @SuppressWarnings({"unchecked"})
+ private static T resolveAnnotationValue(Class expectedType, AnnotationValue value) {
+ Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null);
+ if (unboxedValue != null) {
+ if (expectedType == TypeMirror.class && unboxedValue instanceof String) {
+ return null;
+ }
+ if (!expectedType.isAssignableFrom(unboxedValue.getClass())) {
+ throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName());
+ }
+ }
+ return (T) unboxedValue;
}
public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) {
@@ -470,9 +521,79 @@
if (value == null) {
value = valueMethod.getDefaultValue();
}
+
return value;
}
+ private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7 {
+
+ @Override
+ public Object visitBoolean(boolean b, Void p) {
+ return Boolean.valueOf(b);
+ }
+
+ @Override
+ public Object visitByte(byte b, Void p) {
+ return Byte.valueOf(b);
+ }
+
+ @Override
+ public Object visitChar(char c, Void p) {
+ return c;
+ }
+
+ @Override
+ public Object visitDouble(double d, Void p) {
+ return d;
+ }
+
+ @Override
+ public Object visitFloat(float f, Void p) {
+ return f;
+ }
+
+ @Override
+ public Object visitInt(int i, Void p) {
+ return i;
+ }
+
+ @Override
+ public Object visitLong(long i, Void p) {
+ return i;
+ }
+
+ @Override
+ public Object visitShort(short s, Void p) {
+ return s;
+ }
+
+ @Override
+ public Object visitString(String s, Void p) {
+ return s;
+ }
+
+ @Override
+ public Object visitType(TypeMirror t, Void p) {
+ return t;
+ }
+
+ @Override
+ public Object visitEnumConstant(VariableElement c, Void p) {
+ return c.getConstantValue();
+ }
+
+ @Override
+ public Object visitAnnotation(AnnotationMirror a, Void p) {
+ return a;
+ }
+
+ @Override
+ public Object visitArray(List extends AnnotationValue> vals, Void p) {
+ return vals;
+ }
+
+ }
+
public static boolean getAnnotationValueBoolean(AnnotationMirror mirror, String name) {
return (Boolean) getAnnotationValue(mirror, name).getValue();
}
@@ -591,6 +712,14 @@
}
String qualified1 = getQualifiedName(type1);
String qualified2 = getQualifiedName(type2);
+
+ if (type1.getKind() == TypeKind.ARRAY || type2.getKind() == TypeKind.ARRAY) {
+ if (type1.getKind() == TypeKind.ARRAY && type2.getKind() == TypeKind.ARRAY) {
+ return typeEquals(((ArrayType) type1).getComponentType(), ((ArrayType) type2).getComponentType());
+ } else {
+ return false;
+ }
+ }
return qualified1.equals(qualified2);
}
@@ -619,7 +748,7 @@
return true;
}
- // search for any supertypes
+ // search for any super types
TypeElement exceptionTypeElement = fromTypeMirror(exceptionType);
List superTypes = getSuperTypes(exceptionTypeElement);
for (TypeElement typeElement : superTypes) {
@@ -648,7 +777,7 @@
Set typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type)));
String typeName = getQualifiedName(type);
if (!typeSuperSet.contains(Throwable.class.getCanonicalName()) && !typeName.equals(Throwable.class.getCanonicalName())) {
- throw new IllegalArgumentException("Given does not extend Throwable.");
+ throw new IllegalArgumentException("Given type does not extend Throwable.");
}
return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || typeName.equals(RuntimeException.class.getCanonicalName());
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java Wed Mar 13 20:05:30 2013 +0100
@@ -204,7 +204,7 @@
return v.visitExecutable(this, p);
}
- public static CodeExecutableElement clone(ProcessingEnvironment env, ExecutableElement method) {
+ public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) {
CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString());
for (TypeMirror thrownType : method.getThrownTypes()) {
copy.addThrownType(thrownType);
@@ -220,7 +220,6 @@
for (Element element : method.getEnclosedElements()) {
copy.add(element);
}
- copy.setBody(Utils.getMethodBody(env, method));
copy.getModifiers().addAll(method.getModifiers());
return copy;
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Wed Mar 13 20:05:30 2013 +0100
@@ -495,7 +495,7 @@
}
public CodeTreeBuilder create() {
- return new CodeTreeBuilder(null);
+ return new CodeTreeBuilder(this);
}
public CodeTreeBuilder type(TypeMirror type) {
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java Wed Mar 13 20:05:30 2013 +0100
@@ -123,6 +123,14 @@
writeClassImpl(e);
}
+ private String useImport(TypeMirror type) {
+ if (imports != null) {
+ return imports.useImport(type);
+ } else {
+ return Utils.getSimpleName(type);
+ }
+ }
+
private void writeClassImpl(CodeTypeElement e) {
for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
visitAnnotation(annotation);
@@ -137,12 +145,12 @@
}
write(e.getSimpleName());
if (e.getSuperclass() != null && !getQualifiedName(e.getSuperclass()).equals("java.lang.Object")) {
- write(" extends ").write(typeSimpleName(e.getSuperclass()));
+ write(" extends ").write(useImport(e.getSuperclass()));
}
if (e.getImplements().size() > 0) {
write(" implements ");
for (int i = 0; i < e.getImplements().size(); i++) {
- write(typeSimpleName(e.getImplements().get(i)));
+ write(useImport(e.getImplements().get(i)));
if (i < e.getImplements().size() - 1) {
write(", ");
}
@@ -267,7 +275,7 @@
}
} else {
writeModifiers(f.getModifiers());
- write(typeSimpleName(f.asType()));
+ write(useImport(f.asType()));
if (f.getEnclosingElement().getKind() == ElementKind.METHOD) {
ExecutableElement method = (ExecutableElement) f.getEnclosingElement();
@@ -287,7 +295,7 @@
}
public void visitAnnotation(AnnotationMirror e) {
- write("@").write(typeSimpleName(e.getAnnotationType()));
+ write("@").write(useImport(e.getAnnotationType()));
if (!e.getElementValues().isEmpty()) {
write("(");
@@ -395,14 +403,14 @@
@Override
public Void visitType(TypeMirror t, Void p) {
- write(typeSimpleName(t));
+ write(useImport(t));
write(".class");
return null;
}
@Override
public Void visitEnumConstant(VariableElement c, Void p) {
- write(typeSimpleName(c.asType()));
+ write(useImport(c.asType()));
write(".");
write(c.getSimpleName().toString());
return null;
@@ -458,7 +466,7 @@
writeModifiers(e.getModifiers());
if (e.getReturnType() != null) {
- write(typeSimpleName(e.getReturnType()));
+ write(useImport(e.getReturnType()));
write(" ");
}
write(e.getSimpleName());
@@ -477,7 +485,7 @@
if (throwables.size() > 0) {
write(" throws ");
for (int i = 0; i < throwables.size(); i++) {
- write(typeSimpleName(throwables.get(i)));
+ write(useImport(throwables.get(i)));
if (i < throwables.size() - 1) {
write(", ");
}
@@ -554,7 +562,7 @@
}
break;
case TYPE:
- write(imports.useImport(e.getType()));
+ write(useImport(e.getType()));
break;
default:
assert false;
@@ -562,10 +570,6 @@
}
}
- private static String typeSimpleName(TypeMirror type) {
- return Utils.getSimpleName(type);
- }
-
protected void writeHeader() {
// default implementation does nothing
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java Wed Mar 13 20:05:30 2013 +0100
@@ -359,6 +359,100 @@
public void visitAnnotation(AnnotationMirror e) {
addImport(e.getAnnotationType());
+ if (!e.getElementValues().isEmpty()) {
+ Map extends ExecutableElement, ? extends AnnotationValue> values = e.getElementValues();
+ Set extends ExecutableElement> methodsSet = values.keySet();
+ List methodsList = new ArrayList<>();
+ for (ExecutableElement method : methodsSet) {
+ if (values.get(method) == null) {
+ continue;
+ }
+ methodsList.add(method);
+ }
+
+ for (int i = 0; i < methodsList.size(); i++) {
+ AnnotationValue value = values.get(methodsList.get(i));
+ visitAnnotationValue(value);
+ }
+ }
+ }
+
+ public void visitAnnotationValue(AnnotationValue e) {
+ e.accept(new AnnotationValueReferenceVisitor(), null);
+ }
+
+ private class AnnotationValueReferenceVisitor extends AbstractAnnotationValueVisitor7 {
+
+ @Override
+ public Void visitBoolean(boolean b, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitByte(byte b, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitChar(char c, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitDouble(double d, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitFloat(float f, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitInt(int i, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitLong(long i, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitShort(short s, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitString(String s, Void p) {
+ return null;
+ }
+
+ @Override
+ public Void visitType(TypeMirror t, Void p) {
+ addImport(t);
+ return null;
+ }
+
+ @Override
+ public Void visitEnumConstant(VariableElement c, Void p) {
+ addImport(c.asType());
+ return null;
+ }
+
+ @Override
+ public Void visitAnnotation(AnnotationMirror a, Void p) {
+ ReferenceCollector.this.visitAnnotation(a);
+ return null;
+ }
+
+ @Override
+ public Void visitArray(List extends AnnotationValue> vals, Void p) {
+ for (int i = 0; i < vals.size(); i++) {
+ ReferenceCollector.this.visitAnnotationValue(vals.get(i));
+ }
+ return null;
+ }
}
@Override
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java Wed Mar 13 20:05:30 2013 +0100
@@ -39,6 +39,9 @@
}
protected static Object field(Object o, String fieldName) throws Exception {
+ if (o == null) {
+ return null;
+ }
Field field = o.getClass().getField(fieldName);
field.setAccessible(true);
return field.get(o);
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -31,6 +31,7 @@
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.api.*;
import com.oracle.truffle.codegen.processor.api.element.*;
+import com.oracle.truffle.codegen.processor.template.*;
public class ExtensionParser {
@@ -45,25 +46,25 @@
this.extensionContext = new ExtensionContextImpl(context.getEnvironment(), null, factory);
}
- public List parseAll(TypeElement typeElement, List extends Element> elements) {
+ public List parseAll(Template template, List extends Element> elements) {
List generatedMethods = new ArrayList<>();
- parseElement(generatedMethods, typeElement);
+ parseElement(template, generatedMethods, template.getTemplateType());
List extends ExecutableElement> methods = ElementFilter.methodsIn(elements);
for (ExecutableElement method : methods) {
for (VariableElement var : method.getParameters()) {
- parseElement(generatedMethods, var);
+ parseElement(template, generatedMethods, var);
}
- parseElement(generatedMethods, method);
+ parseElement(template, generatedMethods, method);
}
return generatedMethods;
}
- private void parseElement(List elements, Element element) {
+ private void parseElement(Template template, List elements, Element element) {
List extends AnnotationMirror> mirrors = element.getAnnotationMirrors();
for (AnnotationMirror mirror : mirrors) {
- ExtensionProcessor processor = findProcessor(element, mirror);
+ ExtensionProcessor processor = findProcessor(template, mirror);
if (processor != null) {
try {
factory.generatorAnnotationMirror = mirror;
@@ -71,7 +72,7 @@
processor.process(extensionContext, mirror, element);
elements.addAll(extensionContext.returnElements());
} catch (Throwable e) {
- context.getLog().error(element, mirror, "Processor for '%s' failed with exception: \n\n%s.", Utils.getQualifiedName(mirror.getAnnotationType()), Utils.printException(e));
+ template.addError("Processor for '%s' failed with exception: \n\n%s.", Utils.getQualifiedName(mirror.getAnnotationType()), Utils.printException(e));
} finally {
factory.generatorAnnotationMirror = null;
factory.generatorElement = null;
@@ -80,7 +81,7 @@
}
}
- private ExtensionProcessor findProcessor(Element element, AnnotationMirror mirror) {
+ private ExtensionProcessor findProcessor(Template template, AnnotationMirror mirror) {
String processorName = Utils.getQualifiedName(mirror.getAnnotationType());
ExtensionProcessor processor = null;
if (extensions.containsKey(processorName)) {
@@ -88,24 +89,24 @@
} else {
AnnotationMirror foundExtension = Utils.findAnnotationMirror(context.getEnvironment(), mirror.getAnnotationType().asElement(), ExtensionAnnotation.class);
if (foundExtension != null) {
- String className = Utils.getAnnotationValueString(foundExtension, "processorClassName");
+ String className = Utils.getAnnotationValue(String.class, foundExtension, "processorClassName");
Class> processorClass;
try {
processorClass = Class.forName(className);
} catch (ClassNotFoundException e) {
- context.getLog().error(element, mirror, "Could not find processor class '%s' configured in '@%s'.", className, processorName);
+ template.addError("Could not find processor class '%s' configured in '@%s'.", className, processorName);
return null;
}
try {
processor = (ExtensionProcessor) processorClass.newInstance();
} catch (InstantiationException e) {
- context.getLog().error(element, mirror, "Could not instantiate processor class '%s' configured in '@%s'.", className, processorName);
+ template.addError("Could not instantiate processor class '%s' configured in '@%s'.", className, processorName);
return null;
} catch (IllegalAccessException e) {
- context.getLog().error(element, mirror, "Could not access processor class '%s' configured in '@%s'.", className, processorName);
+ template.addError("Could not access processor class '%s' configured in '@%s'.", className, processorName);
return null;
} catch (ClassCastException e) {
- context.getLog().error(element, mirror, "Processor class '%s' configured in '@%s' does not implement '%s'.", className, processorName, ExtensionProcessor.class.getName());
+ template.addError("Processor class '%s' configured in '@%s' does not implement '%s'.", className, processorName, ExtensionProcessor.class.getName());
return null;
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -44,14 +44,14 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
List types = new ArrayList<>();
- types.addAll(Arrays.asList(getNode().getTypeSystem().getPrimitiveTypeMirrors()));
+ types.addAll(getNode().getTypeSystem().getPrimitiveTypeMirrors());
types.add(getContext().getType(void.class));
- ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types.toArray(new TypeMirror[types.size()]), false, Cardinality.ONE);
+ ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types, false, Cardinality.ONE);
List parameters = new ArrayList<>();
parameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true));
- return new MethodSpec(returnTypeSpec, parameters);
+ return new MethodSpec(new ArrayList(), returnTypeSpec, parameters);
}
@Override
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -41,7 +41,7 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- return createDefaultMethodSpec(null);
+ return createDefaultMethodSpec(method, mirror, null);
}
@Override
@@ -51,8 +51,7 @@
for (ExecutableTypeData type : execTypes) {
types.add(type.getType().getPrimitiveType());
}
- TypeMirror[] array = types.toArray(new TypeMirror[types.size()]);
- return new ParameterSpec(valueName, array, false, Cardinality.ONE);
+ return new ParameterSpec(valueName, types, false, Cardinality.ONE);
}
@Override
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -25,9 +25,10 @@
import java.util.*;
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
+import com.oracle.truffle.codegen.processor.node.NodeFieldData.*;
import com.oracle.truffle.codegen.processor.template.*;
import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
@@ -54,10 +55,21 @@
return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
}
- protected final MethodSpec createDefaultMethodSpec(String shortCircuitName) {
+ @SuppressWarnings("unused")
+ protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, String shortCircuitName) {
List defaultParameters = new ArrayList<>();
- ParameterSpec frameSpec = new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true);
- defaultParameters.add(frameSpec);
+
+ if (getNode().supportsFrame()) {
+ defaultParameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true));
+ }
+
+ TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
+
+ List prefixTypes = new ArrayList<>();
+
+ if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(declaredType, template.getNodeType())) {
+ prefixTypes.add(getNode().getTemplateType().asType());
+ }
for (NodeFieldData field : getNode().getFields()) {
if (field.getExecutionKind() == ExecutionKind.IGNORE) {
@@ -65,7 +77,12 @@
}
if (field.getExecutionKind() == ExecutionKind.DEFAULT) {
- defaultParameters.add(createValueParameterSpec(field.getName(), field.getNodeData(), false));
+ ParameterSpec spec = createValueParameterSpec(field.getName(), field.getNodeData(), false);
+ if (field.getKind() == FieldKind.CHILDREN) {
+ spec.setCardinality(Cardinality.MULTIPLE);
+ spec.setIndexed(true);
+ }
+ defaultParameters.add(spec);
} else if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
String valueName = field.getName();
if (shortCircuitName != null && valueName.equals(shortCircuitName)) {
@@ -79,7 +96,7 @@
}
}
- return new MethodSpec(createReturnParameterSpec(), defaultParameters);
+ return new MethodSpec(prefixTypes, createReturnParameterSpec(), defaultParameters);
}
private static String shortCircuitValueName(String valueName) {
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Wed Mar 13 20:05:30 2013 +0100
@@ -35,6 +35,7 @@
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.ast.*;
import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
+import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind;
import com.oracle.truffle.codegen.processor.template.*;
import com.oracle.truffle.codegen.processor.typesystem.*;
@@ -51,73 +52,49 @@
}
private static String factoryClassName(NodeData node) {
- return nodeClassName(node) + "Factory";
- }
-
- private static String nodeClassName(NodeData node) {
- return Utils.getSimpleName(node.getTemplateType().asType());
+ return node.getNodeId() + "Factory";
}
- private static String nodeClassName(SpecializationData specialization) {
- String name = specializationId(specialization);
- name += nodeClassName(specialization.getNode());
- if (name.equals(Utils.getSimpleName(specialization.getNode().getNodeType())) || name.equals(Utils.getSimpleName(specialization.getNode().getTemplateType()))) {
- name = name + "Impl";
+ private static String nodeSpecializationClassName(SpecializationData specialization) {
+ String nodeid = specialization.getNode().getNodeId();
+ if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
+ nodeid = nodeid.substring(0, nodeid.length() - 4);
}
+ String name = Utils.firstLetterUpperCase(nodeid);
+ name += Utils.firstLetterUpperCase(specialization.getId());
+ name += "Node";
return name;
}
- private static String specializationId(SpecializationData specialization) {
- String name = "";
- NodeData node = specialization.getNode();
- if (node.getSpecializations().length > 1) {
- name = specialization.getMethodName();
- if (name.startsWith("do")) {
- name = name.substring(2);
- }
- }
- return name;
- }
-
- private static String valueName(NodeFieldData field) {
- return field.getName() + "Value";
- }
-
private static String valueName(ActualParameter param) {
- NodeData node = (NodeData) param.getMethod().getTemplate();
- NodeFieldData field = node.findField(param.getSpecification().getName());
- if (field != null) {
- return valueName(field);
- } else {
- return param.getSpecification().getName();
- }
+ return param.getName();
}
private static String castValueName(ActualParameter parameter) {
return valueName(parameter) + "Cast";
}
- private static String castValueName(NodeFieldData field) {
- return valueName(field) + "Cast";
- }
-
- private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) {
- if (forceFrame) {
- method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frame"));
+ private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean includeHidden) {
+ if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
+ method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
}
for (ActualParameter parameter : specialization.getParameters()) {
ParameterSpec spec = parameter.getSpecification();
if (forceFrame && spec.getName().equals("frame")) {
continue;
}
+ if (!includeHidden && parameter.isHidden()) {
+ continue;
+ }
+
method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter)));
}
}
- private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame) {
- if (forceFrame) {
- builder.string("frame");
+ private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeHidden) {
+ if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
+ builder.string("frameValue");
}
for (ActualParameter parameter : specialization.getParameters()) {
ParameterSpec spec = parameter.getSpecification();
@@ -125,7 +102,11 @@
continue;
}
- if (unexpectedValueName != null && spec.getName().equals(unexpectedValueName)) {
+ if (!includeHidden && parameter.isHidden()) {
+ continue;
+ }
+
+ if (unexpectedValueName != null && parameter.getName().equals(unexpectedValueName)) {
builder.string("ex.getResult()");
} else {
builder.string(valueName(parameter));
@@ -133,14 +114,18 @@
}
}
- private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization) {
+ private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization, boolean includeHidden) {
NodeData node = targetSpecialization.getNode();
TypeSystemData typeSystem = node.getTypeSystem();
for (ActualParameter targetParameter : targetSpecialization.getParameters()) {
- ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getSpecification().getName());
+ ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getName());
TypeData targetType = targetParameter.getActualTypeData(typeSystem);
+ if (!includeHidden && (targetParameter.isHidden() || valueParameter.isHidden())) {
+ continue;
+ }
+
TypeData valueType = null;
if (valueParameter != null) {
valueType = valueParameter.getActualTypeData(typeSystem);
@@ -158,31 +143,63 @@
return getSimpleName(operation.getTemplateType()) + "Gen";
}
- private static void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod method) {
+ private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) {
body.startGroup();
- if (body.findMethod().getModifiers().contains(STATIC)) {
- body.string(THIS_NODE_LOCAL_VAR_NAME);
+ ExecutableElement method = templateMethod.getMethod();
+ if (method == null) {
+ throw new IllegalStateException("Cannot call synthtetic operation methods.");
+ }
+ TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
+ NodeData node = (NodeData) templateMethod.getTemplate();
+
+ boolean accessible = templateMethod.canBeAccessedByInstanceOf(node.getNodeType());
+ if (accessible) {
+ if (body.findMethod().getModifiers().contains(STATIC)) {
+ body.string(THIS_NODE_LOCAL_VAR_NAME);
+ } else {
+ body.string("super");
+ }
} else {
- body.string("super");
+ if (method.getModifiers().contains(STATIC)) {
+ body.type(targetClass.asType());
+ } else {
+ ActualParameter parameter = templateMethod.getParameters().get(0);
+ if (castedValues) {
+ NodeFieldData field = node.findField(parameter.getSpecification().getName());
+ NodeData fieldNode = field.getNodeData();
+ ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem()));
+ if (execType.hasUnexpectedValue(getContext())) {
+ body.string(castValueName(parameter));
+ } else {
+ body.string(valueName(parameter));
+ }
+ } else {
+ body.string(valueName(parameter));
+ }
+ }
}
body.string(".");
- body.startCall(method.getMethodName());
+ body.startCall(method.getSimpleName().toString());
}
- private static String generatedGenericMethodName(SpecializationData specialization) {
+ private String generatedGenericMethodName(SpecializationData specialization) {
final String prefix = "generic";
if (specialization == null) {
return prefix;
}
+ if (!specialization.getNode().getGenericSpecialization().isUseSpecializationsForGeneric() || !specialization.getNode().needsRewrites(context)) {
+ return prefix;
+ }
+
SpecializationData prev = null;
for (SpecializationData current : specialization.getNode().getSpecializations()) {
if (specialization == current) {
if (prev == null || prev.isUninitialized()) {
return prefix;
} else {
- return prefix + specializationId(current);
+ return prefix + current.getId();
}
}
prev = current;
@@ -237,34 +254,32 @@
}
if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
- builder.startIf().string(conditionPrefix).end().startBlock();
+ builder.startIf();
+ builder.string(conditionPrefix);
+ builder.end().startBlock();
ifCount++;
}
builder.tree(guardedStatements);
builder.end(ifCount);
- if (ifCount > 0 && elseStatements != null) {
- builder.startElseBlock();
+ if (elseStatements != null && ifCount > 0) {
builder.tree(elseStatements);
- builder.end();
}
-
return builder.getRoot();
}
- private static CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization,
- boolean onSpecialization) {
+ private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization) {
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
- if (guardedSpecialization.getGuards().length > 0) {
+ if (guardedSpecialization.getGuards().size() > 0) {
// Explicitly specified guards
for (SpecializationGuardData guard : guardedSpecialization.getGuards()) {
if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) {
builder.string(andOperator);
- startCallOperationMethod(builder, guard.getGuardDeclaration());
- addValueParameterNamesWithCasts(builder, valueSpecialization, guardedSpecialization);
+ startCallOperationMethod(builder, guard.getGuardDeclaration(), true);
+ addValueParameterNamesWithCasts(builder, valueSpecialization, guardedSpecialization, false);
builder.end().end(); // call
andOperator = " && ";
@@ -276,13 +291,14 @@
}
private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
- NodeData node = guardedSpecialization.getNode();
-
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
// Implict guards based on method signature
- for (NodeFieldData field : node.getFields()) {
- ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName());
- ActualParameter valueParam = valueSpecialization.findParameter(field.getName());
+ for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
+ NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
+ if (field == null) {
+ continue;
+ }
+ ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
CodeTree cast = createCast(parent, field, valueParam, guardedParam);
if (cast == null) {
@@ -295,14 +311,15 @@
}
private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
- NodeData node = guardedSpecialization.getNode();
-
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
// Implict guards based on method signature
String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
- for (NodeFieldData field : node.getFields()) {
- ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName());
- ActualParameter valueParam = valueSpecialization.findParameter(field.getName());
+ for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
+ NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
+ if (field == null) {
+ continue;
+ }
+ ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
if (implicitGuard == null) {
@@ -339,7 +356,7 @@
}
startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getActualTypeData(node.getTypeSystem())));
- builder.string(valueName(field));
+ builder.string(valueName(source));
builder.end().end(); // call
if (field.isShortCircuit()) {
@@ -371,7 +388,7 @@
CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), valueName(target));
- return createLazyAssignment(parent, castValueName(field), target.getActualType(), condition, value);
+ return createLazyAssignment(parent, castValueName(target), target.getActualType(), condition, value);
}
/**
@@ -408,6 +425,10 @@
return builder.getRoot();
}
+ private void emitEncounteredSynthetic(CodeTreeBuilder builder) {
+ builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end();
+ }
+
@Override
protected void createChildren(NodeData node) {
Map> childTypes = new LinkedHashMap<>();
@@ -492,13 +513,15 @@
if (node.needsFactory()) {
createFactoryMethods(node, clazz, createVisibility);
- if (node.getSpecializations().length > 1) {
+ if (node.getSpecializations().size() > 1) {
clazz.add(createCreateSpecializedMethod(node, createVisibility));
}
- if (node.needsRewrites(getContext())) {
+ if (node.needsRewrites(context)) {
clazz.add(createSpecializeMethod(node));
+ }
+ if (node.getGenericSpecialization() != null) {
List genericMethods = createGeneratedGenericMethod(node);
for (CodeExecutableElement method : genericMethods) {
clazz.add(method);
@@ -515,6 +538,7 @@
clazz.add(createCreateNodeSpecializedMethod(node));
clazz.add(createGetNodeClassMethod(node));
clazz.add(createGetNodeSignaturesMethod(node));
+ clazz.add(createGetChildrenSignatureMethod(node));
clazz.add(createGetInstanceMethod(node, createVisibility));
clazz.add(createInstanceConstant(node, clazz.asType()));
}
@@ -565,21 +589,62 @@
builder.startStaticCall(getContext().getType(Arrays.class), "asList");
List constructors = findUserConstructors(node);
for (ExecutableElement constructor : constructors) {
- builder.startGroup();
- builder.type(getContext().getType(Arrays.class));
- builder.string(".<").type(getContext().getType(Class.class)).string(">");
- builder.startCall("asList");
- for (VariableElement param : constructor.getParameters()) {
- builder.typeLiteral(param.asType());
- }
- builder.end();
- builder.end();
+ builder.tree(createAsList(builder, Utils.asTypeMirrors(constructor.getParameters()), classType));
}
builder.end();
builder.end();
return method;
}
+ private CodeExecutableElement createGetChildrenSignatureMethod(NodeData node) {
+ Types types = getContext().getEnvironment().getTypeUtils();
+ TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
+ TypeMirror classType = getContext().getType(Class.class);
+ TypeMirror nodeType = getContext().getTruffleTypes().getNode();
+ TypeMirror wildcardNodeType = types.getWildcardType(nodeType, null);
+ classType = types.getDeclaredType(Utils.fromTypeMirror(classType), wildcardNodeType);
+ TypeMirror returnType = types.getDeclaredType(listType, classType);
+
+ CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getExecutionSignature");
+ CodeTreeBuilder builder = method.createBuilder();
+
+ List signatureTypes = new ArrayList<>();
+ assert !node.getSpecializations().isEmpty();
+ SpecializationData data = node.getSpecializations().get(0);
+ for (ActualParameter parameter : data.getParameters()) {
+ ParameterSpec spec = parameter.getSpecification();
+ NodeFieldData field = node.findField(spec.getName());
+ if (field == null) {
+ continue;
+ }
+
+ TypeMirror type;
+ if (field.getKind() == FieldKind.CHILDREN && field.getType().getKind() == TypeKind.ARRAY) {
+ type = ((ArrayType) field.getType()).getComponentType();
+ } else {
+ type = field.getType();
+ }
+
+ signatureTypes.add(type);
+ }
+
+ builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
+ return method;
+ }
+
+ private CodeTree createAsList(CodeTreeBuilder parent, List types, TypeMirror elementClass) {
+ CodeTreeBuilder builder = parent.create();
+ builder.startGroup();
+ builder.type(getContext().getType(Arrays.class));
+ builder.string(".<").type(elementClass).string(">");
+ builder.startCall("asList");
+ for (TypeMirror typeMirror : types) {
+ builder.typeLiteral(typeMirror);
+ }
+ builder.end().end();
+ return builder.getRoot();
+ }
+
private CodeExecutableElement createCreateNodeMethod(NodeData node) {
CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments");
@@ -717,15 +782,21 @@
}
List nodeTypesList = new ArrayList<>();
+ TypeMirror prev = null;
+ boolean allSame = true;
for (NodeData child : children) {
- nodeTypesList.add(child.getTemplateType().asType());
+ nodeTypesList.add(child.getNodeType());
+ if (prev != null && !Utils.typeEquals(child.getNodeType(), prev)) {
+ allSame = false;
+ }
+ prev = child.getNodeType();
}
TypeMirror commonNodeSuperType = Utils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()]));
Types types = getContext().getEnvironment().getTypeUtils();
TypeMirror factoryType = getContext().getType(NodeFactory.class);
TypeMirror baseType;
- if (children.size() == 1) {
+ if (allSame) {
baseType = types.getDeclaredType(Utils.fromTypeMirror(factoryType), commonNodeSuperType);
} else {
baseType = types.getDeclaredType(Utils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null));
@@ -793,10 +864,10 @@
CodeTreeBuilder body = method.createBuilder();
body.startReturn();
- if (node.getSpecializations().length == 0) {
+ if (node.getSpecializations().isEmpty()) {
body.null_();
} else {
- body.startNew(nodeClassName(node.getSpecializations()[0]));
+ body.startNew(nodeSpecializationClassName(node.getSpecializations().get(0)));
for (VariableElement var : method.getParameters()) {
body.string(var.getSimpleName().toString());
}
@@ -828,14 +899,14 @@
body.startElseIf();
}
body.string("specializationClass == ").type(type.getBoxedType()).string(".class").end().startBlock();
- body.startReturn().startNew(nodeClassName(specialization));
+ body.startReturn().startNew(nodeSpecializationClassName(specialization));
body.string(THIS_NODE_LOCAL_VAR_NAME);
body.end().end(); // new, return
body.end(); // if
}
}
- body.startReturn().startNew(nodeClassName(node.getGenericSpecialization()));
+ body.startReturn().startNew(nodeSpecializationClassName(node.getGenericSpecialization()));
body.string(THIS_NODE_LOCAL_VAR_NAME);
body.end().end();
return method;
@@ -845,17 +916,17 @@
CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize");
method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
- addValueParameters(method, node.getGenericSpecialization(), false);
+ addValueParameters(method, node.getGenericSpecialization(), false, true);
CodeTreeBuilder body = method.createBuilder();
- body.startStatement().string("boolean allowed = (minimumState == ").string(nodeClassName(node.getSpecializations()[0])).string(".class)").end();
+ body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
- for (int i = 1; i < node.getSpecializations().length; i++) {
- SpecializationData specialization = node.getSpecializations()[i];
- body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeClassName(specialization)).string(".class)").end();
+ for (int i = 1; i < node.getSpecializations().size(); i++) {
+ SpecializationData specialization = node.getSpecializations().get(i);
+ body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(specialization)).string(".class)").end();
CodeTreeBuilder guarded = new CodeTreeBuilder(body);
- guarded.startReturn().startNew(nodeClassName(specialization));
+ guarded.startReturn().startNew(nodeSpecializationClassName(specialization));
guarded.string(THIS_NODE_LOCAL_VAR_NAME);
guarded.end().end();
@@ -868,14 +939,14 @@
private List createGeneratedGenericMethod(NodeData node) {
TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getActualType();
- if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) {
+ if (node.getGenericSpecialization().isUseSpecializationsForGeneric() && node.needsRewrites(context)) {
List methods = new ArrayList<>();
- SpecializationData[] specializations = node.getSpecializations();
+ List specializations = node.getSpecializations();
SpecializationData prev = null;
- for (int i = 0; i < specializations.length; i++) {
- SpecializationData current = specializations[i];
- SpecializationData next = i + 1 < specializations.length ? specializations[i + 1] : null;
+ for (int i = 0; i < specializations.size(); i++) {
+ SpecializationData current = specializations.get(i);
+ SpecializationData next = i + 1 < specializations.size() ? specializations.get(i + 1) : null;
if (prev == null || current.isUninitialized()) {
prev = current;
continue;
@@ -883,7 +954,7 @@
String methodName = generatedGenericMethodName(current);
CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName);
method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
- addValueParameters(method, node.getGenericSpecialization(), true);
+ addValueParameters(method, node.getGenericSpecialization(), true, true);
emitGeneratedGenericSpecialization(method.createBuilder(), current, next);
@@ -896,7 +967,7 @@
} else {
CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null));
method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
- addValueParameters(method, node.getGenericSpecialization(), true);
+ addValueParameters(method, node.getGenericSpecialization(), true, true);
emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0);
return Arrays.asList(method);
}
@@ -908,44 +979,51 @@
CodeTree invokeMethod = invokeMethodBuilder.getRoot();
if (next != null) {
- invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, null);
+ CodeTreeBuilder nextBuilder = builder.create();
+
+ nextBuilder.startReturn().startCall(generatedGenericMethodName(next));
+ nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME);
+ addValueParameterNames(nextBuilder, next, null, true, true);
+ nextBuilder.end().end();
+
+ invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot());
}
builder.tree(invokeMethod);
if (next != null) {
builder.end();
-
- builder.startReturn().startCall(generatedGenericMethodName(next));
- builder.string(THIS_NODE_LOCAL_VAR_NAME);
- addValueParameterNames(builder, next, null, true);
- builder.end().end();
}
}
private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) {
- if (specialization.getExceptions().length > 0) {
+ if (!specialization.getExceptions().isEmpty()) {
builder.startTryBlock();
}
- builder.startReturn();
- startCallOperationMethod(builder, specialization);
- addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization);
- builder.end().end(); // start call operation
- builder.end(); // return
+ if (specialization.getMethod() == null) {
+ emitEncounteredSynthetic(builder);
+ } else {
+ builder.startReturn();
+ startCallOperationMethod(builder, specialization, true);
+ addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization, false);
+ builder.end().end(); // start call operation
+ builder.end(); // return
+ }
- if (specialization.getExceptions().length > 0) {
+ if (!specialization.getExceptions().isEmpty()) {
for (SpecializationThrowsData exception : specialization.getExceptions()) {
builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level);
builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo()));
builder.string(THIS_NODE_LOCAL_VAR_NAME);
- addValueParameterNames(builder, exception.getTransitionTo(), null, true);
+ addValueParameterNames(builder, exception.getTransitionTo(), null, true, true);
builder.end().end();
}
builder.end();
}
}
+
}
private class SpecializedNodeFactory extends ClassElementFactory {
@@ -957,7 +1035,7 @@
@Override
public CodeTypeElement create(SpecializationData specialization) {
NodeData node = specialization.getNode();
- CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeClassName(specialization), node.getNodeType(), false);
+ CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), node.getNodeType(), false);
return clazz;
}
@@ -981,7 +1059,7 @@
CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
if (method.getParameters().size() == 1) {
CodeVariableElement var = CodeVariableElement.clone(method.getParameters().get(0));
- var.setName("frame");
+ var.setName("frameValue");
method.getParameters().set(0, var);
}
method.getModifiers().remove(Modifier.ABSTRACT);
@@ -996,7 +1074,7 @@
}
if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) {
- buildSpecializeStateMethod(clazz, specialization);
+ buildSpecializeAndExecute(clazz, specialization);
}
}
@@ -1014,7 +1092,7 @@
CodeTree primaryExecuteCall = null;
CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder();
- buildExecute(executeBuilder, null, execType);
+ buildExecute(executeBuilder, null, null, execType);
primaryExecuteCall = executeBuilder.getRoot();
if (needsTry) {
@@ -1122,7 +1200,7 @@
builder.startCall(factoryClassName(node), "specialize");
builder.string("this");
builder.typeLiteral(builder.findMethod().getEnclosingElement().asType());
- addValueParameterNames(builder, specialization, null, false);
+ addValueParameterNames(builder, specialization, null, false, true);
builder.end(); // call replace, call specialize
} else {
builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end();
@@ -1134,29 +1212,28 @@
private CodeTree createExecute(CodeTreeBuilder parent, SpecializationData specialization) {
NodeData node = specialization.getNode();
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
- if (specialization.getExceptions().length > 0) {
+ if (!specialization.getExceptions().isEmpty()) {
builder.startTryBlock();
}
- if ((specialization.isUninitialized() || specialization.isGeneric()) && node.needsRewrites(getContext())) {
+ if (specialization.getMethod() == null && !node.needsRewrites(context)) {
+ emitEncounteredSynthetic(builder);
+ } else if (specialization.isUninitialized() || specialization.isGeneric()) {
builder.startReturn().startCall(factoryClassName(node), generatedGenericMethodName(null));
builder.string("this");
- addValueParameterNames(builder, specialization, null, true);
+ addValueParameterNames(builder, specialization, null, true, true);
builder.end().end();
} else {
builder.startReturn();
- if (specialization.isUninitialized()) {
- startCallOperationMethod(builder, specialization.getNode().getGenericSpecialization());
- } else {
- startCallOperationMethod(builder, specialization);
- }
- addValueParameterNames(builder, specialization, null, false);
+ startCallOperationMethod(builder, specialization, false);
+ addValueParameterNames(builder, specialization, null, false, false);
+
builder.end().end(); // operation call
builder.end(); // return
}
- if (specialization.getExceptions().length > 0) {
+ if (!specialization.getExceptions().isEmpty()) {
for (SpecializationThrowsData exception : specialization.getExceptions()) {
builder.end().startCatchBlock(exception.getJavaClass(), "ex");
builder.tree(createReturnSpecializeAndExecute(parent, exception.getTransitionTo(), null));
@@ -1168,18 +1245,14 @@
private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) {
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
- for (NodeFieldData field : specialization.getNode().getFields()) {
- if (field.getExecutionKind() == ExecutionKind.IGNORE) {
+
+ for (ActualParameter parameter : specialization.getParameters()) {
+ NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName());
+ if (field == null) {
continue;
}
- ActualParameter parameterType = specialization.findParameter(field.getName());
-
- if (parameterType.getActualTypeData(specialization.getNode().getTypeSystem()).isGeneric()) {
- buildGenericValueExecute(builder, specialization, field, null);
- } else {
- buildSpecializedValueExecute(builder, specialization, field);
- }
+ buildFieldExecute(builder, specialization, parameter, field, null);
}
return builder.getRoot();
}
@@ -1187,37 +1260,58 @@
private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
for (TemplateMethod listener : node.getSpecializationListeners()) {
builder.startStatement();
- startCallOperationMethod(builder, listener);
- addValueParameterNames(builder, listener, null, false);
+ startCallOperationMethod(builder, listener, false);
+ addValueParameterNames(builder, listener, null, false, false);
builder.end().end();
builder.end(); // statement
}
}
- private void buildGenericValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field, NodeFieldData exceptionSpec) {
- ActualParameter specParameter = specialization.findParameter(field.getName());
- NodeData node = specialization.getNode();
- boolean shortCircuit = startShortCircuit(builder, specialization, field, exceptionSpec);
+ private void buildFieldExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field, ActualParameter exceptionParam) {
+ boolean shortCircuit = startShortCircuit(builder, specialization, param, exceptionParam);
+ ExecutableTypeData execType = field.getNodeData().findExecutableType(param.getActualTypeData(field.getNodeData().getTypeSystem()));
+ boolean unexpected = execType.hasUnexpectedValue(getContext());
- builder.startStatement();
- if (!shortCircuit) {
- builder.type(specialization.getNode().getTypeSystem().getGenericType());
- builder.string(" ");
+ if (!shortCircuit && unexpected) {
+ builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end();
+ }
+
+ if (unexpected) {
+ builder.startTryBlock();
}
- builder.string(valueName(specParameter));
- builder.string(" = ");
- ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), specParameter.getActualTypeData(node.getTypeSystem()));
- if (genericExecutableType == null) {
- throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes()));
+ if (!shortCircuit && !unexpected) {
+ builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).string(" = ");
+ } else {
+ builder.startStatement().string(valueName(param)).string(" = ");
}
- buildExecute(builder, field, genericExecutableType);
+ buildExecute(builder, param, field, execType);
builder.end();
+ if (unexpected) {
+ builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
+ SpecializationData generic = specialization.getNode().getGenericSpecialization();
+ boolean execute = false;
+ for (ActualParameter exParam : generic.getParameters()) {
+ NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName());
+ if (exField == null) {
+ continue;
+ }
+ if (execute) {
+ buildFieldExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param);
+ } else if (exParam.getName().equals(param.getName())) {
+ execute = true;
+ }
+ }
+ builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param));
+ builder.end(); // catch block
+ }
+
endShortCircuit(builder, shortCircuit);
+ builder.newLine();
}
- private void buildExecute(CodeTreeBuilder builder, NodeFieldData field, ExecutableTypeData execType) {
+ private void buildExecute(CodeTreeBuilder builder, ActualParameter parameter, NodeFieldData field, ExecutableTypeData execType) {
if (field != null) {
Element accessElement = field.getAccessElement();
if (accessElement.getKind() == ElementKind.METHOD) {
@@ -1227,60 +1321,28 @@
} else {
throw new AssertionError();
}
+ if (parameter.getSpecification().isIndexed()) {
+ builder.string("[" + parameter.getIndex() + "]");
+ }
builder.string(".");
}
builder.startCall(execType.getMethodName());
- if (execType.getParameters().length == 1) {
- builder.string("frame");
+ if (execType.getParameters().size() == 1) {
+ builder.string("frameValue");
}
builder.end();
}
- private void buildSpecializedValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field) {
- ActualParameter param = specialization.findParameter(field.getName());
- boolean shortCircuit = startShortCircuit(builder, specialization, field, null);
-
- if (!shortCircuit) {
- builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end();
- }
-
- ExecutableTypeData execType = field.getNodeData().findExecutableType(param.getActualTypeData(field.getNodeData().getTypeSystem()));
-
- if (execType.hasUnexpectedValue(getContext())) {
- builder.startTryBlock();
+ private boolean startShortCircuit(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
+ NodeFieldData forField = specialization.getNode().findField(parameter.getSpecification().getName());
+ if (forField == null) {
+ return false;
}
- builder.startStatement().string(valueName(field)).string(" = ");
- buildExecute(builder, field, execType);
- builder.end();
-
- if (execType.hasUnexpectedValue(getContext())) {
- builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
- boolean execute = false;
- for (NodeFieldData exField : specialization.getNode().getFields()) {
- if (exField.getExecutionKind() == ExecutionKind.IGNORE) {
- continue;
- }
- if (execute) {
- buildGenericValueExecute(builder, specialization.getNode().getGenericSpecialization(), exField, field);
- } else if (exField == field) {
- execute = true;
- }
- }
- builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param.getSpecification()));
- builder.end(); // catch block
- }
-
- endShortCircuit(builder, shortCircuit);
- builder.newLine();
- }
-
- private boolean startShortCircuit(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData forField, NodeFieldData exceptionField) {
if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) {
return false;
}
- ActualParameter parameter = specialization.findParameter(forField.getName());
ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
int shortCircuitIndex = 0;
@@ -1294,16 +1356,16 @@
}
builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
- ShortCircuitData shortCircuitData = specialization.getShortCircuits()[shortCircuitIndex];
+ ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
- startCallOperationMethod(builder, shortCircuitData);
- addValueParameterNames(builder, shortCircuitData, exceptionField != null ? exceptionField.getName() : null, false);
+ startCallOperationMethod(builder, shortCircuitData, false);
+ addValueParameterNames(builder, shortCircuitData, exceptionParam != null ? exceptionParam.getName() : null, false, false);
builder.end().end(); // call operation
builder.end(); // statement
builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType()));
- builder.startIf().string(shortCircuitParam.getSpecification().getName()).end();
+ builder.startIf().string(shortCircuitParam.getName()).end();
builder.startBlock();
return true;
@@ -1315,11 +1377,11 @@
}
}
- private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) {
+ private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ActualParameter exceptionParam) {
CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
specializeCall.startCall("specializeAndExecute");
- specializeCall.string(nodeClassName(nextSpecialization) + ".class");
- addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionSpec != null ? exceptionSpec.getName() : null, true);
+ specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
+ addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getName() : null, true, true);
specializeCall.end().end();
CodeTreeBuilder builder = new CodeTreeBuilder(parent);
@@ -1329,7 +1391,7 @@
return builder.getRoot();
}
- private void buildSpecializeStateMethod(CodeTypeElement clazz, SpecializationData specialization) {
+ private void buildSpecializeAndExecute(CodeTypeElement clazz, SpecializationData specialization) {
NodeData node = specialization.getNode();
TypeData returnType = specialization.getReturnType().getActualTypeData(node.getTypeSystem());
ExecutableTypeData returnExecutableType = node.findExecutableType(returnType);
@@ -1340,7 +1402,7 @@
if (canThrowUnexpected) {
method.addThrownType(getUnexpectedValueException());
}
- addValueParameters(method, specialization.getNode().getGenericSpecialization(), true);
+ addValueParameters(method, specialization.getNode().getGenericSpecialization(), true, true);
clazz.add(method);
CodeTreeBuilder builder = method.createBuilder();
@@ -1351,7 +1413,7 @@
builder.startStatement();
builder.startCall("replace");
builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState");
- addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false);
+ addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true);
builder.end();
builder.end(); // call replace
builder.end(); // statement
@@ -1362,7 +1424,7 @@
CodeTreeBuilder genericExecute = CodeTreeBuilder.createBuilder();
genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName);
genericExecute.string("this");
- addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true);
+ addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true);
genericExecute.end(); // call generated generic
CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot());
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Wed Mar 13 20:05:30 2013 +0100
@@ -35,22 +35,85 @@
public class NodeData extends Template {
- private NodeData parent;
- private List declaredChildren;
+ private final String nodeId;
+ private NodeData declaringNode;
+ private List declaredChildren = new ArrayList<>();
+
+ private TypeSystemData typeSystem;
+ private List fields;
+ private TypeMirror nodeType;
+ private ParameterSpec instanceParameterSpec;
+
+ private List specializations;
+ private List specializationListeners;
+ private List guards;
+ private List executableTypes;
+ private List shortCircuits;
- private final TypeSystemData typeSystem;
+ public NodeData(TypeElement type, String id) {
+ super(type, null, null);
+ this.nodeId = id;
+ }
+
+ public NodeData(NodeData splitSource, String templateMethodName, String nodeId) {
+ super(splitSource.getTemplateType(), templateMethodName, null);
+ this.nodeId = nodeId;
+ this.declaringNode = splitSource.declaringNode;
+ this.declaredChildren = splitSource.declaredChildren;
+ this.typeSystem = splitSource.typeSystem;
+ this.nodeType = splitSource.nodeType;
+ this.specializations = splitSource.specializations;
+ this.specializationListeners = splitSource.specializationListeners;
+ this.guards = splitSource.guards;
+ this.executableTypes = splitSource.executableTypes;
+ this.shortCircuits = splitSource.shortCircuits;
+ this.fields = splitSource.fields;
+ }
+
+ void setTypeSystem(TypeSystemData typeSystem) {
+ this.typeSystem = typeSystem;
+ }
- private NodeFieldData[] fields;
- private SpecializationData[] specializations;
- private TemplateMethod[] specializationListeners;
- private GuardData[] guards;
- private ExecutableTypeData[] executableTypes;
+ @Override
+ protected List findChildContainers() {
+ List sinks = new ArrayList<>();
+ if (declaredChildren != null) {
+ sinks.addAll(declaredChildren);
+ }
+ if (typeSystem != null) {
+ sinks.add(typeSystem);
+ }
+ if (specializations != null) {
+ sinks.addAll(specializations);
+ }
+ if (specializationListeners != null) {
+ sinks.addAll(specializationListeners);
+ }
+ if (guards != null) {
+ sinks.addAll(guards);
+ }
+ if (executableTypes != null) {
+ sinks.addAll(executableTypes);
+ }
+ if (shortCircuits != null) {
+ sinks.addAll(shortCircuits);
+ }
+ if (fields != null) {
+ sinks.addAll(fields);
+ }
+ return sinks;
+ }
- private TypeMirror nodeType;
+ public ParameterSpec getInstanceParameterSpec() {
+ return instanceParameterSpec;
+ }
- public NodeData(TypeElement type, TypeSystemData typeSystem) {
- super(type, null);
- this.typeSystem = typeSystem;
+ public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
+ this.instanceParameterSpec = instanceParameter;
+ }
+
+ public String getNodeId() {
+ return nodeId;
}
public TypeMirror getNodeType() {
@@ -71,6 +134,15 @@
return !noSpecialization;
}
+ public boolean supportsFrame() {
+ for (ExecutableTypeData execType : executableTypes) {
+ if (execType.findParameter("frameValue") == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public List getNodeChildren() {
List children = new ArrayList<>();
for (NodeData child : getDeclaredChildren()) {
@@ -86,12 +158,12 @@
this.declaredChildren = declaredChildren;
for (NodeData child : declaredChildren) {
- child.parent = this;
+ child.declaringNode = this;
}
}
public NodeData getParent() {
- return parent;
+ return declaringNode;
}
public List getDeclaredChildren() {
@@ -107,22 +179,16 @@
for (SpecializationData specialization : getSpecializations()) {
methods.add(specialization);
- if (specialization.getShortCircuits() != null) {
- methods.addAll(Arrays.asList(specialization.getShortCircuits()));
- }
}
- methods.addAll(Arrays.asList(getSpecializationListeners()));
- methods.addAll(Arrays.asList(getExecutableTypes()));
- methods.addAll(Arrays.asList(getGuards()));
+ methods.addAll(getSpecializationListeners());
+ methods.addAll(getExecutableTypes());
+ methods.addAll(getGuards());
+ methods.addAll(getShortCircuits());
return methods;
}
- public TemplateMethod[] getSpecializationListeners() {
- return specializationListeners;
- }
-
public List findGuards(String name) {
List foundGuards = new ArrayList<>();
for (GuardData guardData : getGuards()) {
@@ -133,10 +199,6 @@
return foundGuards;
}
- public ExecutableTypeData[] getExecutableTypes() {
- return executableTypes;
- }
-
public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) {
List types = findGenericExecutableTypes(context);
for (ExecutableTypeData availableType : types) {
@@ -147,6 +209,14 @@
return null;
}
+ public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) {
+ List types = findGenericExecutableTypes(context);
+ if (!types.isEmpty()) {
+ return types.get(0);
+ }
+ return null;
+ }
+
public List findGenericExecutableTypes(ProcessorContext context) {
List types = new ArrayList<>();
for (ExecutableTypeData type : executableTypes) {
@@ -180,47 +250,20 @@
return result;
}
- public TypeMirror[] getExecutablePrimitiveTypeMirrors() {
- TypeMirror[] typeMirrors = new TypeMirror[executableTypes.length];
- for (int i = 0; i < executableTypes.length; i++) {
- typeMirrors[i] = executableTypes[i].getType().getPrimitiveType();
+ public List getExecutablePrimitiveTypeMirrors() {
+ List typeMirrors = new ArrayList<>();
+ for (ExecutableTypeData executableType : executableTypes) {
+ typeMirrors.add(executableType.getType().getPrimitiveType());
}
return typeMirrors;
}
- void setExecutableTypes(ExecutableTypeData[] declaredExecuableTypes) {
- this.executableTypes = declaredExecuableTypes;
- }
-
- void setFields(NodeFieldData[] fields) {
- this.fields = fields;
- }
-
- void setSpecializations(SpecializationData[] specializations) {
- this.specializations = specializations;
- }
-
- void setSpecializationListeners(TemplateMethod[] specializationListeners) {
- this.specializationListeners = specializationListeners;
- }
-
- void setGuards(GuardData[] guards) {
- this.guards = guards;
- }
-
- public GuardData[] getGuards() {
- return guards;
- }
-
public NodeFieldData[] filterFields(FieldKind fieldKind, ExecutionKind usage) {
List filteredFields = new ArrayList<>();
- NodeFieldData[] resolvedFields = getFields();
- if (fields != null) {
- for (NodeFieldData field : resolvedFields) {
- if (usage == null || field.getExecutionKind() == usage) {
- if (fieldKind == null || field.getKind() == fieldKind) {
- filteredFields.add(field);
- }
+ for (NodeFieldData field : getFields()) {
+ if (usage == null || field.getExecutionKind() == usage) {
+ if (fieldKind == null || field.getKind() == fieldKind) {
+ filteredFields.add(field);
}
}
}
@@ -238,18 +281,13 @@
public boolean needsRewrites(ProcessorContext context) {
boolean needsRewrites = false;
- for (NodeFieldData field : getFields()) {
- if (field.getExecutionKind() == ExecutionKind.DEFAULT || field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
- if (!field.getNodeData().hasUnexpectedExecutableTypes(context)) {
- continue;
- }
+ for (SpecializationData specialization : getSpecializations()) {
+ if (specialization.hasRewrite(context)) {
needsRewrites = true;
break;
}
}
-
- needsRewrites &= specializations.length >= 2;
return needsRewrites;
}
@@ -263,37 +301,65 @@
}
public TypeSystemData getTypeSystem() {
- if (typeSystem != null) {
- return typeSystem;
+ return typeSystem;
+ }
+
+ public String dump() {
+ return dump(0);
+ }
+
+ private String dump(int level) {
+ String indent = "";
+ for (int i = 0; i < level; i++) {
+ indent += " ";
+ }
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(String.format("%s%s {", indent, toString()));
+
+ dumpProperty(builder, indent, "templateClass", Utils.getQualifiedName(getTemplateType()));
+ dumpProperty(builder, indent, "typeSystem", getTypeSystem());
+ dumpProperty(builder, indent, "fields", getFields());
+ dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
+ dumpProperty(builder, indent, "specializations", getSpecializations());
+ dumpProperty(builder, indent, "guards", getGuards());
+ dumpProperty(builder, indent, "messages", collectMessages());
+ if (getDeclaredChildren().size() > 0) {
+ builder.append(String.format("\n%s children = [", indent));
+ for (NodeData node : getDeclaredChildren()) {
+ builder.append("\n");
+ builder.append(node.dump(level + 1));
+ }
+ builder.append(String.format("\n%s ]", indent));
+ }
+ builder.append(String.format("%s}", indent));
+ return builder.toString();
+ }
+
+ private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) {
+ if (value instanceof List) {
+ List> list = (List>) value;
+ if (!list.isEmpty()) {
+ b.append(String.format("\n%s %s = %s", indent, propertyName, dumpList((List>) value)));
+ }
} else {
- return null;
+ if (value != null) {
+ b.append(String.format("\n%s %s = %s", indent, propertyName, value));
+ }
}
}
- public NodeFieldData[] getFields() {
- return fields;
- }
-
- public NodeFieldData[] getDeclaredFields() {
- return fields;
- }
-
- public SpecializationData[] getSpecializations() {
- return specializations;
- }
-
- public String dump() {
- StringBuilder b = new StringBuilder();
- b.append(String.format("[name = %s\n" + " typeSystem = %s\n" + " fields = %s\n" + " types = %s\n" + " specializations = %s\n" + " guards = %s\n" + "]",
- Utils.getQualifiedName(getTemplateType()), getTypeSystem(), dumpList(fields), dumpList(getExecutableTypes()), dumpList(getSpecializations()), dumpList(guards)));
- return b.toString();
- }
-
- private static String dumpList(Object[] array) {
+ private static String dumpList(List> array) {
if (array == null) {
return "null";
}
+ if (array.isEmpty()) {
+ return "[]";
+ } else if (array.size() == 1) {
+ return "[" + array.get(0).toString() + "]";
+ }
+
StringBuilder b = new StringBuilder();
b.append("[");
for (Object object : array) {
@@ -315,4 +381,76 @@
return null;
}
+ public List getFields() {
+ return fields;
+ }
+
+ void setFields(List fields) {
+ this.fields = 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;
+ }
+
+ public List getGuards() {
+ return guards;
+ }
+
+ public List getExecutableTypes() {
+ return executableTypes;
+ }
+
+ public List getShortCircuits() {
+ return shortCircuits;
+ }
+
+ void setSpecializations(List specializations) {
+ this.specializations = specializations;
+ if (this.specializations != null) {
+ for (SpecializationData specialization : specializations) {
+ specialization.setNode(this);
+ }
+ }
+ }
+
+ void setSpecializationListeners(List specializationListeners) {
+ this.specializationListeners = specializationListeners;
+ }
+
+ void setGuards(List guards) {
+ this.guards = guards;
+ }
+
+ void setExecutableTypes(List executableTypes) {
+ this.executableTypes = executableTypes;
+ }
+
+ void setShortCircuits(List shortCircuits) {
+ this.shortCircuits = shortCircuits;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + getNodeId() + "]";
+ }
+
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java Wed Mar 13 20:05:30 2013 +0100
@@ -25,10 +25,12 @@
import javax.lang.model.element.*;
import javax.lang.model.type.*;
-public class NodeFieldData {
+import com.oracle.truffle.codegen.processor.template.*;
+
+public class NodeFieldData extends MessageContainer {
public enum FieldKind {
- FIELD, CHILD, CHILDREN
+ CHILD, CHILDREN
}
public enum ExecutionKind {
@@ -41,21 +43,39 @@
private final FieldKind fieldKind;
private final ExecutionKind executionKind;
- private final NodeData nodeData;
+ private NodeData nodeData;
- public NodeFieldData(NodeData typeNodeData, VariableElement fieldElement, Element accessElement, AnnotationMirror childAnnotationMirror, FieldKind fieldKind, ExecutionKind executionKind) {
+ public NodeFieldData(VariableElement fieldElement, Element accessElement, AnnotationMirror childAnnotationMirror, FieldKind fieldKind, ExecutionKind executionKind) {
this.fieldElement = fieldElement;
this.accessElement = accessElement;
this.childAnnotationMirror = childAnnotationMirror;
- this.nodeData = typeNodeData;
this.fieldKind = fieldKind;
this.executionKind = executionKind;
}
+ NodeFieldData(NodeFieldData field) {
+ this.fieldElement = field.fieldElement;
+ this.accessElement = field.accessElement;
+ this.childAnnotationMirror = field.childAnnotationMirror;
+ this.fieldKind = field.fieldKind;
+ this.executionKind = field.executionKind;
+ this.nodeData = field.nodeData;
+ }
+
+ @Override
+ public Element getMessageElement() {
+ return fieldElement;
+ }
+
public boolean isShortCircuit() {
return executionKind == ExecutionKind.SHORT_CIRCUIT;
}
+ void setNode(NodeData nodeData) {
+ this.nodeData = nodeData;
+ getMessages().addAll(nodeData.collectMessages());
+ }
+
public VariableElement getFieldElement() {
return fieldElement;
}
@@ -90,7 +110,7 @@
@Override
public String toString() {
- return "NodeFieldData[name=" + getName() + ", kind=" + fieldKind + ", execution=" + executionKind + "]";
+ return "NodeFieldData[name=" + getName() + ", kind=" + fieldKind + ", execution=" + executionKind + ", node=" + getNodeData().toString() + "]";
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -28,6 +28,7 @@
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
+import javax.tools.Diagnostic.*;
import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.api.nodes.Node.Child;
@@ -41,11 +42,9 @@
public class NodeParser extends TemplateParser {
- public static final List> ANNOTATIONS = Arrays.asList(Generic.class, GuardCheck.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class,
- SpecializationGuard.class, SpecializationListener.class, SpecializationThrows.class);
+ public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class);
private Map parsedNodes;
- private TypeElement originalType;
public NodeParser(ProcessorContext c) {
super(c);
@@ -54,23 +53,37 @@
@Override
protected NodeData parse(Element element, AnnotationMirror mirror) {
assert element instanceof TypeElement;
+ NodeData node = null;
try {
parsedNodes = new HashMap<>();
- originalType = (TypeElement) element;
-
- return parseInnerClassHierarchy((TypeElement) element);
- } finally {
+ node = resolveNode((TypeElement) element);
if (Log.DEBUG) {
- NodeData parsed = parsedNodes.get(Utils.getQualifiedName(originalType));
- if (parsed != null) {
+ NodeData parsed = parsedNodes.get(Utils.getQualifiedName((TypeElement) element));
+ if (node != null) {
String dump = parsed.dump();
- log.error("Node parsed: %s", dump);
- System.out.println("Parsed: " + dump);
+ log.message(Kind.ERROR, null, null, null, dump);
+ System.out.println(dump);
}
}
+ } finally {
parsedNodes = null;
- originalType = null;
}
+
+ return node;
+ }
+
+ @Override
+ protected NodeData filterErrorElements(NodeData model) {
+ for (Iterator iterator = model.getDeclaredChildren().iterator(); iterator.hasNext();) {
+ NodeData node = filterErrorElements(iterator.next());
+ if (node == null) {
+ iterator.remove();
+ }
+ }
+ if (model.hasErrors()) {
+ return null;
+ }
+ return model;
}
@Override
@@ -78,182 +91,426 @@
return true;
}
- private NodeData parseInnerClassHierarchy(TypeElement rootType) {
+ private NodeData resolveNode(TypeElement rootType) {
+ String typeName = Utils.getQualifiedName(rootType);
+ if (parsedNodes.containsKey(typeName)) {
+ return parsedNodes.get(typeName);
+ }
+
List extends TypeElement> types = ElementFilter.typesIn(rootType.getEnclosedElements());
+
List children = new ArrayList<>();
for (TypeElement childElement : types) {
- NodeData childNode = parseInnerClassHierarchy(childElement);
+ NodeData childNode = resolveNode(childElement);
if (childNode != null) {
children.add(childNode);
}
}
- NodeData rootNode = resolveNode(rootType);
- if (rootNode == null && children.size() > 0) {
- rootNode = new NodeData(rootType, null);
+
+ NodeData rootNode = parseNode(rootType);
+ boolean hasErrors = rootNode != null ? rootNode.hasErrors() : false;
+ if ((rootNode == null || hasErrors) && children.size() > 0) {
+ rootNode = new NodeData(rootType, rootType.getSimpleName().toString());
}
+
+ parsedNodes.put(typeName, rootNode);
+
if (rootNode != null) {
+ children.addAll(rootNode.getDeclaredChildren());
rootNode.setDeclaredChildren(children);
}
return rootNode;
}
- private NodeData resolveNode(TypeElement currentType) {
- String typeName = Utils.getQualifiedName(currentType);
- if (!parsedNodes.containsKey(typeName)) {
- NodeData node = parseNode(currentType);
- if (node != null) {
- parsedNodes.put(typeName, node);
- }
- return node;
- }
- return parsedNodes.get(typeName);
- }
-
private NodeData parseNode(TypeElement type) {
if (Utils.findAnnotationMirror(processingEnv, type, GeneratedBy.class) != null) {
- // generated nodes get called again.
+ // generated nodes should not get called again.
return null;
}
- if (!Utils.isAssignable(type.asType(), context.getTruffleTypes().getNode())) {
+
+ AnnotationMirror methodNodes = Utils.findAnnotationMirror(processingEnv, type, NodeClass.class);
+
+ if (methodNodes == null && !Utils.isAssignable(type.asType(), context.getTruffleTypes().getNode())) {
return null; // not a node
}
if (type.getModifiers().contains(Modifier.PRIVATE)) {
- return null; // not visible
+ // TODO error message here!?
+ return null; // not visible, not a node
+ }
+
+ TypeElement nodeType;
+ boolean needsSplit;
+ if (methodNodes != null) {
+ needsSplit = methodNodes != null;
+ nodeType = Utils.fromTypeMirror(Utils.getAnnotationValue(TypeMirror.class, methodNodes, "value"));
+ } else {
+ needsSplit = false;
+ nodeType = type;
+ }
+
+ NodeData nodeData = parseNodeData(type, nodeType);
+ if (nodeData.hasErrors()) {
+ return nodeData; // error sync point
}
List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(type));
- List typeHierarchy = findSuperClasses(new ArrayList(), type);
- Collections.reverse(typeHierarchy);
-
- AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
- if (typeSystemMirror == null) {
- log.error(type, "No @%s annotation found in type hierarchy.", TypeSystemReference.class.getSimpleName());
- return null;
- }
-
- TypeMirror typeSytemType = Utils.getAnnotationValueType(typeSystemMirror, "value");
- final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
- if (typeSystem == null) {
- log.error(type, "The used type system '%s' is invalid.", Utils.getQualifiedName(typeSytemType));
- return null;
- }
-
- NodeData nodeData = new NodeData(type, typeSystem);
-
- nodeData.setExtensionElements(getExtensionParser().parseAll(type, elements));
+ nodeData.setExtensionElements(getExtensionParser().parseAll(nodeData, elements));
if (nodeData.getExtensionElements() != null) {
elements.addAll(nodeData.getExtensionElements());
}
+ parseMethods(nodeData, elements);
- List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements));
-
- nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()]));
+ if (nodeData.hasErrors()) {
+ return nodeData;
+ }
- parsedNodes.put(Utils.getQualifiedName(type), nodeData);
+ List nodes;
+ if (needsSplit) {
+ nodes = splitNodeData(nodeData);
+ } else {
+ nodes = new ArrayList<>();
+ nodes.add(nodeData);
+ }
- NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy);
- if (fields == null) {
- return null;
+ for (NodeData splittedNode : nodes) {
+ finalizeSpecializations(splittedNode);
+ verifyNode(splittedNode);
+ }
+
+ if (needsSplit) {
+ nodeData.setDeclaredChildren(nodes);
+ nodeData.setSpecializationListeners(new ArrayList());
+ nodeData.setSpecializations(new ArrayList());
+ return nodeData;
+ } else {
+ return nodeData;
}
- nodeData.setFields(fields);
+ }
+
+ private static List splitNodeData(NodeData node) {
+ SortedMap> groupedSpecializations = groupByNodeId(node.getSpecializations());
+ SortedMap> groupedListeners = groupByNodeId(node.getSpecializationListeners());
+
+ Set ids = new TreeSet<>();
+ ids.addAll(groupedSpecializations.keySet());
+ ids.addAll(groupedListeners.keySet());
+
+ List splitted = new ArrayList<>();
+ for (String id : ids) {
+ List specializations = groupedSpecializations.get(id);
+ List listeners = groupedListeners.get(id);
+
+ if (specializations == null) {
+ specializations = new ArrayList<>();
+ }
- List genericSpecializations = new GenericParser(context, nodeData).parse(elements);
- List guards = new GuardParser(context, nodeData, nodeData.getTypeSystem()).parse(elements);
- nodeData.setGuards(guards.toArray(new GuardData[guards.size()]));
+ 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);
+
+ splitted.add(copy);
+ }
+
+ node.setSpecializations(new ArrayList());
+ node.setSpecializationListeners(new ArrayList());
+
+ return splitted;
+ }
- SpecializationMethodParser specializationParser = new SpecializationMethodParser(context, nodeData);
- List specializations = specializationParser.parse(elements);
- List shortCircuits = new ShortCircuitParser(context, nodeData).parse(elements);
- List listeners = new SpecializationListenerParser(context, nodeData).parse(elements);
+ 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 void parseMethods(final NodeData node, List elements) {
+ node.setGuards(new GuardParser(context, node, node.getTypeSystem()).parse(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);
- if (specializations == null || genericSpecializations == null || shortCircuits == null || listeners == null || guards == null) {
- return null;
+ List allSpecializations = new ArrayList<>();
+ allSpecializations.addAll(generics);
+ allSpecializations.addAll(specializations);
+
+ node.setSpecializations(allSpecializations);
+ }
+
+ private void finalizeSpecializations(final NodeData node) {
+ List specializations = new ArrayList<>(node.getSpecializations());
+
+ if (specializations.isEmpty()) {
+ return;
+ }
+
+ List generics = new ArrayList<>();
+ for (SpecializationData spec : specializations) {
+ if (spec.isGeneric()) {
+ generics.add(spec);
+ }
+ }
+
+ 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 (genericSpecializations.size() > 1) {
- for (SpecializationData generic : genericSpecializations) {
- log.error(generic.getMethod(), "Only one method with @%s is allowed per operation.", Generic.class.getSimpleName());
+ if (generics.size() > 1) {
+ for (SpecializationData generic : generics) {
+ generic.addError("Only @%s is allowed per operation.", Generic.class.getSimpleName());
}
- return null;
- } else if (genericSpecializations.size() == 1) {
- genericSpecialization = genericSpecializations.get(0);
+ return;
+ } else if (generics.size() == 1) {
+ genericSpecialization = generics.get(0);
+ } else if (node.needsRewrites(context)) {
+ SpecializationData specialization = specializations.get(0);
+ GenericParser parser = new GenericParser(context, node);
+ MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, null);
+
+ ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context);
+ assert anyGenericReturnType != null;
+
+ ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType().getPrimitiveType(), 0, false);
+ List parameters = new ArrayList<>();
+ for (ActualParameter specializationParameter : specialization.getParameters()) {
+ ParameterSpec parameterSpec = specification.findParameterSpec(specializationParameter.getSpecification().getName());
+ NodeFieldData field = node.findField(parameterSpec.getName());
+ TypeMirror actualType;
+ if (field == null) {
+ actualType = specializationParameter.getActualType();
+ } else {
+ ExecutableTypeData paramType = field.getNodeData().findAnyGenericExecutableType(context);
+ assert paramType != null;
+ actualType = paramType.getType().getPrimitiveType();
+ }
+ parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isHidden()));
+ }
+ TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
+ genericSpecialization = new SpecializationData(genericMethod, true, false);
+
+ specializations.add(genericSpecialization);
}
- if (specializations.size() > 1 && genericSpecialization == null) {
- log.error(type, "Need a @%s method.", Generic.class.getSimpleName());
- return null;
+ if (genericSpecialization != null) {
+ CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized");
+ TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(),
+ genericSpecialization.getReturnType(), genericSpecialization.getParameters());
+ specializations.add(new SpecializationData(uninializedMethod, false, true));
}
Collections.sort(specializations, new Comparator() {
@Override
public int compare(SpecializationData o1, SpecializationData o2) {
- return compareSpecialization(typeSystem, o1, o2);
+ return compareSpecialization(node.getTypeSystem(), o1, o2);
}
});
- List allSpecializations = new ArrayList<>(specializations);
- if (genericSpecialization != null) {
- allSpecializations.add(genericSpecialization);
- CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized");
- TemplateMethod uninializedMethod = new TemplateMethod(nodeData, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(),
- genericSpecialization.getReturnType(), genericSpecialization.getParameters());
- allSpecializations.add(0, new SpecializationData(uninializedMethod, false, true));
+ node.setSpecializations(specializations);
+
+ for (SpecializationData specialization : specializations) {
+ specialization.setId(findUniqueSpecializationId(specialization));
}
+ }
- for (SpecializationData specialization : allSpecializations) {
- specialization.setNode(nodeData);
+ private static String findUniqueSpecializationId(SpecializationData specialization) {
+
+ String name;
+ if (specialization.isGeneric()) {
+ name = "Generic";
+ } else if (specialization.isUninitialized()) {
+ name = "Uninitialized";
+ } else {
+ List specializations = new ArrayList<>(specialization.getNode().getSpecializations());
+ for (ListIterator iterator = specializations.listIterator(); iterator.hasNext();) {
+ SpecializationData data = iterator.next();
+ if (data.isGeneric() || data.isUninitialized()) {
+ iterator.remove();
+ }
+ }
+
+ Map> usedIds = new HashMap<>();
+ for (SpecializationData other : specializations) {
+ for (ActualParameter param : other.getReturnTypeAndParameters()) {
+ if (other.getNode().findField(param.getSpecification().getName()) == null) {
+ continue;
+ }
+
+ Set types = usedIds.get(param.getSpecification());
+ if (types == null) {
+ types = new HashSet<>();
+ usedIds.put(param.getSpecification(), types);
+ }
+ types.add(Utils.getTypeId(param.getActualType()));
+ }
+ }
+
+ List ambiguousSpecs = new ArrayList<>();
+ for (ActualParameter param : specialization.getReturnTypeAndParameters()) {
+ Set ids = usedIds.get(param.getSpecification());
+ if (ids != null && ids.size() > 1) {
+ ambiguousSpecs.add(param.getSpecification());
+ }
+ }
+
+ String specializationId = findSpecializationId(specialization, ambiguousSpecs);
+ int specializationIndex = 0;
+ int totalIndex = 0;
+
+ for (SpecializationData other : specializations) {
+ String id = findSpecializationId(other, ambiguousSpecs);
+ if (id.equals(specializationId)) {
+ totalIndex++;
+ if (specialization == other) {
+ specializationIndex = totalIndex;
+ }
+ }
+ }
+
+ if (specializationIndex != totalIndex) {
+ name = specializationId + specializationIndex;
+ } else {
+ name = specializationId;
+ }
}
+ return name;
+ }
- // verify order is not ambiguous
- if (!verifySpecializationOrder(typeSystem, specializations)) {
- return null;
+ private static String findSpecializationId(SpecializationData specialization, List specs) {
+ boolean allSame = true;
+ ActualParameter prevParam = specialization.getReturnType();
+ for (ParameterSpec spec : specs) {
+ ActualParameter param = specialization.findParameter(spec);
+ if (!Utils.typeEquals(prevParam.getActualType(), param.getActualType())) {
+ allSame = false;
+ break;
+ }
+ prevParam = param;
}
- nodeData.setSpecializations(allSpecializations.toArray(new SpecializationData[allSpecializations.size()]));
- nodeData.setSpecializationListeners(listeners.toArray(new TemplateMethod[listeners.size()]));
+ if (allSame) {
+ return Utils.getTypeId(prevParam.getActualType());
+ } else {
+ StringBuilder nameBuilder = new StringBuilder();
+ nameBuilder.append(Utils.getTypeId(prevParam.getActualType()));
+ for (ParameterSpec spec : specs) {
+ ActualParameter param = specialization.findParameter(spec);
+ nameBuilder.append(Utils.getTypeId(param.getActualType()));
+ }
+ return nameBuilder.toString();
+ }
+ }
- if (!verifyMissingAbstractMethods(nodeData, elements)) {
- return null;
- }
+ private void verifyNode(NodeData nodeData) {
+ // verify specialization parameter length
+ verifySpecializationParameters(nodeData);
+
+ // verify order is not ambiguous
+ verifySpecializationOrder(nodeData);
+
+ verifyMissingAbstractMethods(nodeData);
+
+ assignShortCircuitsToSpecializations(nodeData);
- if (!assignShortCircuitsToSpecializations(nodeData, allSpecializations, shortCircuits)) {
- return null;
- }
+ verifyConstructors(nodeData);
+
+// if (!verifyNamingConvention(specializations, "do")) {
+// return null;
+// }
+//
+// if (!verifyNamesUnique(specializations)) {
+// return null;
+// }
+
+ verifyNamingConvention(nodeData.getShortCircuits(), "needs");
- if (!verifyConstructors(nodeData)) {
- return null;
+ verifySpecializationThrows(nodeData);
+ }
+
+ private NodeData parseNodeData(TypeElement templateType, TypeElement nodeType) {
+ List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(nodeType));
+ List typeHierarchy = findSuperClasses(new ArrayList(), nodeType);
+ Collections.reverse(typeHierarchy);
+ NodeData nodeData = new NodeData(templateType, templateType.getSimpleName().toString());
+
+ AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
+ if (typeSystemMirror == null) {
+ nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), nodeType.getQualifiedName().toString());
+ return nodeData;
}
- if (!verifyNamingConvention(specializations, "do")) {
- return null;
- }
-
- if (!verifyNamesUnique(specializations)) {
- return null;
+ TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
+ final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
+ if (typeSystem == null) {
+ nodeData.addError("The used type system '%s' is invalid.", Utils.getQualifiedName(typeSytemType));
+ return nodeData;
}
- if (!verifyNamingConvention(shortCircuits, "needs")) {
- return null;
- }
+ nodeData.setNodeType(nodeType.asType());
+ nodeData.setTypeSystem(typeSystem);
- if (!verifySpecializationThrows(typeSystem, specializations)) {
- return null;
- }
+ List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements));
+ nodeData.setExecutableTypes(executableTypes);
+ parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
+ nodeData.setFields(parseFields(nodeData, elements, typeHierarchy));
return nodeData;
}
- private boolean verifyMissingAbstractMethods(NodeData nodeData, List elements) {
- if (nodeData.needsFactory()) {
+ private static void verifySpecializationParameters(NodeData nodeData) {
+ boolean valid = true;
+ int args = -1;
+ for (SpecializationData specializationData : nodeData.getSpecializations()) {
+ int specializationArgs = 0;
+ for (ActualParameter param : specializationData.getParameters()) {
+ if (!param.getSpecification().isOptional()) {
+ specializationArgs++;
+ }
+ }
+ if (args != -1 && args != specializationArgs) {
+ valid = false;
+ break;
+ }
+ args = specializationArgs;
+ }
+ if (!valid) {
+ for (SpecializationData specialization : nodeData.getSpecializations()) {
+ specialization.addError("All specializations must have the same number of arguments.");
+ }
+ }
+ }
+
+ private void verifyMissingAbstractMethods(NodeData nodeData) {
+ if (!nodeData.needsFactory()) {
// missing abstract methods only needs to be implemented
// if we need go generate factory for it.
- return true;
+ return;
}
+ List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(nodeData.getTemplateType()));
+
Set unusedElements = new HashSet<>(elements);
for (TemplateMethod method : nodeData.getAllTemplateMethods()) {
unusedElements.remove(method.getMethod());
@@ -262,24 +519,20 @@
unusedElements.removeAll(nodeData.getExtensionElements());
}
- boolean valid = true;
for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
- context.getLog().error(nodeData.getTemplateType(), "The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()),
- Utils.getReadableSignature(unusedMethod));
- valid = false;
+ nodeData.addError("The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()), Utils.getReadableSignature(unusedMethod));
}
}
+ }
+
+ private void verifyConstructors(NodeData nodeData) {
+ if (!nodeData.needsRewrites(context)) {
+ // no specialization constructor is needed if the node never rewrites.
+ return;
+ }
- return valid;
- }
-
- private boolean verifyConstructors(NodeData nodeData) {
TypeElement type = Utils.fromTypeMirror(nodeData.getNodeType());
- if (!nodeData.needsRewrites(context)) {
- // no specialization constructor is needed if the node never rewrites.
- return true;
- }
List constructors = ElementFilter.constructorsIn(type.getEnclosedElements());
for (ExecutableElement e : constructors) {
@@ -287,20 +540,17 @@
TypeMirror firstArg = e.getParameters().get(0).asType();
if (Utils.typeEquals(firstArg, nodeData.getNodeType())) {
if (e.getModifiers().contains(Modifier.PRIVATE)) {
- context.getLog().error(e, "The specialization constructor must not be private.");
- return false;
+ nodeData.addError("The specialization constructor must not be private.");
} else if (constructors.size() <= 1) {
- context.getLog().error(e, "The specialization constructor must not be the only constructor. The definition of an alternative constructor is required.");
- return false;
+ nodeData.addError("The specialization constructor must not be the only constructor. The definition of an alternative constructor is required.");
}
- return true;
+ return;
}
}
}
// not found
- context.getLog().error(type, "Specialization constructor '%s(%s previousNode) { this(...); }' is required.", Utils.getSimpleName(type), Utils.getSimpleName(type));
- return false;
+ nodeData.addError("Specialization constructor '%s(%s previousNode) { this(...); }' is required.", Utils.getSimpleName(type), Utils.getSimpleName(type));
}
private static List filterExecutableTypes(List executableTypes) {
@@ -347,13 +597,13 @@
return null;
}
- private NodeFieldData[] parseFields(NodeData nodeData, List extends Element> elements, final List typeHierarchy) {
+ private List parseFields(NodeData nodeData, List extends Element> elements, final List typeHierarchy) {
AnnotationMirror executionOrderMirror = findFirstAnnotation(typeHierarchy, ExecuteChildren.class);
List executionDefinition = null;
if (executionOrderMirror != null) {
executionDefinition = new ArrayList<>();
- for (Object object : Utils.getAnnotationValueList(executionOrderMirror, "value")) {
- executionDefinition.add((String) object);
+ for (String object : Utils.getAnnotationValueList(String.class, executionOrderMirror, "value")) {
+ executionDefinition.add(object);
}
}
@@ -361,12 +611,10 @@
for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
if (mirror != null) {
- shortCircuits.add(Utils.getAnnotationValueString(mirror, "value"));
+ shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value"));
}
}
- boolean valid = true;
-
List fields = new ArrayList<>();
for (VariableElement var : ElementFilter.fieldsIn(elements)) {
if (var.getModifiers().contains(Modifier.STATIC)) {
@@ -380,23 +628,12 @@
}
NodeFieldData field = parseField(nodeData, var, shortCircuits);
- if (field != null) {
- if (field.getExecutionKind() != ExecutionKind.IGNORE) {
- fields.add(field);
- }
- } else {
- valid = false;
+ if (field.getExecutionKind() != ExecutionKind.IGNORE) {
+ fields.add(field);
}
}
-
- // TODO parse getters
- if (!valid) {
- return null;
- }
-
- NodeFieldData[] fieldArray = fields.toArray(new NodeFieldData[fields.size()]);
- sortByExecutionOrder(fieldArray, executionDefinition == null ? Collections. emptyList() : executionDefinition, typeHierarchy);
- return fieldArray;
+ sortByExecutionOrder(fields, executionDefinition == null ? Collections. emptyList() : executionDefinition, typeHierarchy);
+ return fields;
}
private NodeFieldData parseField(NodeData parentNodeData, VariableElement var, Set foundShortCircuits) {
@@ -424,34 +661,29 @@
nodeType = getComponentType(var.asType());
kind = FieldKind.CHILDREN;
} else {
- mirror = null;
+ execution = ExecutionKind.IGNORE;
nodeType = null;
- kind = FieldKind.FIELD;
- execution = ExecutionKind.IGNORE;
+ mirror = null;
+ kind = null;
}
- NodeData fieldNodeData = null;
+ NodeFieldData fieldData = new NodeFieldData(var, findAccessElement(var), mirror, kind, execution);
if (nodeType != null) {
- fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeType));
- Element errorElement = Utils.typeEquals(parentNodeData.getTemplateType().asType(), var.getEnclosingElement().asType()) ? var : parentNodeData.getTemplateType();
+ NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeType));
+ fieldData.setNode(fieldNodeData);
if (fieldNodeData == null) {
- // TODO redirect errors from resolve.
- context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
- return null;
+ fieldData.addError("Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
} else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) {
- // TODO better error handling for (no or multiple?)
- context.getLog().error(errorElement, "No executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
- return null;
+ fieldData.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
+ }
+
+ // TODO correct handling of access elements
+ if (var.getModifiers().contains(Modifier.PRIVATE) && Utils.typeEquals(var.getEnclosingElement().asType(), parentNodeData.getTemplateType().asType())) {
+ execution = ExecutionKind.IGNORE;
}
}
-
- // TODO correct handling of access elements
- if (var.getModifiers().contains(Modifier.PRIVATE) && Utils.typeEquals(var.getEnclosingElement().asType(), parentNodeData.getTemplateType().asType())) {
- execution = ExecutionKind.IGNORE;
- }
-
- return new NodeFieldData(fieldNodeData, var, findAccessElement(var), mirror, kind, execution);
+ return fieldData;
}
private Element findAccessElement(VariableElement variableElement) {
@@ -482,8 +714,8 @@
}
}
- private static void sortByExecutionOrder(NodeFieldData[] fields, final List executionOrder, final List typeHierarchy) {
- Arrays.sort(fields, new Comparator() {
+ private static void sortByExecutionOrder(List fields, final List executionOrder, final List typeHierarchy) {
+ Collections.sort(fields, new Comparator() {
@Override
public int compare(NodeFieldData o1, NodeFieldData o2) {
@@ -505,18 +737,16 @@
});
}
- private boolean assignShortCircuitsToSpecializations(NodeData nodeData, List specializations, List shortCircuits) {
-
- Map> groupedShortCircuits = groupShortCircuits(shortCircuits);
+ private void assignShortCircuitsToSpecializations(NodeData node) {
+ Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits());
boolean valid = true;
-
- for (NodeFieldData field : nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) {
+ for (NodeFieldData field : node.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) {
String valueName = field.getName();
List availableCircuits = groupedShortCircuits.get(valueName);
if (availableCircuits == null || availableCircuits.isEmpty()) {
- log.error(nodeData.getTemplateType(), "@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
+ node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
valid = false;
continue;
}
@@ -531,7 +761,7 @@
if (!sameMethodName) {
for (ShortCircuitData circuit : availableCircuits) {
- log.error(circuit.getMethod(), circuit.getMarkerAnnotation(), "All short circuits for short cut value '%s' must have the same method name.", valueName);
+ circuit.addError("All short circuits for short cut value '%s' must have the same method name.", valueName);
}
valid = false;
continue;
@@ -539,14 +769,14 @@
ShortCircuitData genericCircuit = null;
for (ShortCircuitData circuit : availableCircuits) {
- if (isGenericShortCutMethod(nodeData, circuit)) {
+ if (isGenericShortCutMethod(node, circuit)) {
genericCircuit = circuit;
break;
}
}
if (genericCircuit == null) {
- log.error(nodeData.getTemplateType(), "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
+ node.addError("No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
valid = false;
continue;
}
@@ -559,67 +789,48 @@
}
if (!valid) {
- return valid;
+ return;
}
- NodeFieldData[] fields = nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT);
- for (SpecializationData specialization : specializations) {
- ShortCircuitData[] assignedShortCuts = new ShortCircuitData[fields.length];
+ NodeFieldData[] fields = node.filterFields(null, ExecutionKind.SHORT_CIRCUIT);
+ for (SpecializationData specialization : node.getSpecializations()) {
+ 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)) {
- assignedShortCuts[i] = circuit;
+ compatibleShortCircuit = circuit;
}
}
- if (assignedShortCuts[i] == null) {
- assignedShortCuts[i] = genericShortCircuit;
+ if (compatibleShortCircuit == null) {
+ compatibleShortCircuit = genericShortCircuit;
}
+ assignedShortCuts.add(compatibleShortCircuit);
}
specialization.setShortCircuits(assignedShortCuts);
}
- return true;
}
- private boolean verifyNamingConvention(List extends TemplateMethod> methods, String prefix) {
- boolean valid = true;
+ 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)) {
- log.error(m1.getMethod(), m1.getMarkerAnnotation(), "Naming convention: method name must start with '%s'.", prefix);
- valid = false;
+ m1.addError("Naming convention: method name must start with '%s'.", prefix);
}
}
- return valid;
- }
-
- private boolean verifyNamesUnique(List extends TemplateMethod> methods) {
- boolean valid = true;
- for (int i = 0; i < methods.size(); i++) {
- TemplateMethod m1 = methods.get(i);
- for (int j = i + 1; j < methods.size(); j++) {
- TemplateMethod m2 = methods.get(j);
-
- if (m1.getMethodName().equalsIgnoreCase(m2.getMethodName())) {
- log.error(m1.getMethod(), m1.getMarkerAnnotation(), "Method name '%s' used multiple times", m1.getMethodName());
- log.error(m2.getMethod(), m2.getMarkerAnnotation(), "Method name '%s' used multiple times", m1.getMethodName());
- return false;
- }
- }
- }
- return valid;
}
private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
- for (NodeFieldData field : node.getFields()) {
- ActualParameter parameter = method.findParameter(field.getName());
- if (parameter == null) {
+ for (ActualParameter parameter : method.getParameters()) {
+ NodeFieldData field = node.findField(parameter.getSpecification().getName());
+ if (field == null) {
continue;
}
ExecutableTypeData found = null;
@@ -668,7 +879,10 @@
return collection;
}
- private boolean verifySpecializationOrder(TypeSystemData typeSystem, List specializations) {
+ private static void verifySpecializationOrder(NodeData node) {
+ TypeSystemData typeSystem = node.getTypeSystem();
+ 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++) {
@@ -678,56 +892,39 @@
if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
int specOrder = m1.getOrder() - m2.getOrder();
if (specOrder == 0) {
- log.error(m1.getMethod(), m1.getMarkerAnnotation(), "Order value %d used multiple times", m1.getOrder());
- log.error(m2.getMethod(), m2.getMarkerAnnotation(), "Order value %d used multiple times", m1.getOrder());
- return false;
+ 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)) {
- log.error(m1.getMethod(), m1.getMarkerAnnotation(), "Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
- log.error(m2.getMethod(), m2.getMarkerAnnotation(), "Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
- return false;
+ 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);
- log.error(m.getMethod(), m.getMarkerAnnotation(), "Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
- return false;
+ m.addError("Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
+ return;
}
}
}
- return true;
}
- private boolean verifySpecializationThrows(TypeSystemData typeSystem, List specializations) {
+ private static void verifySpecializationThrows(NodeData node) {
Map specializationMap = new HashMap<>();
- for (SpecializationData spec : specializations) {
+ for (SpecializationData spec : node.getSpecializations()) {
specializationMap.put(spec.getMethodName(), spec);
}
- boolean valid = true;
- for (SpecializationData sourceSpecialization : specializations) {
+ for (SpecializationData sourceSpecialization : node.getSpecializations()) {
if (sourceSpecialization.getExceptions() != null) {
for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) {
- SpecializationData targetSpecialization = specializationMap.get(throwsData.getTransitionToName());
- AnnotationValue value = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "transitionTo");
-
- if (targetSpecialization == null) {
- log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value, "Specialization with name '%s' not found.", throwsData.getTransitionToName());
- valid = false;
- } else if (compareSpecialization(typeSystem, sourceSpecialization, targetSpecialization) >= 0) {
- log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value,
- "The order of the target specializalization must be higher than the source specialization.", throwsData.getTransitionToName());
- valid = false;
- }
-
for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) {
if (otherThrowsData != throwsData && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
- AnnotationValue javaClassValue = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "javaClass");
- log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), javaClassValue, "Duplicate exception type.", throwsData.getTransitionToName());
- valid = false;
+ throwsData.addError("Duplicate exception type.");
}
}
}
}
}
- return valid;
}
private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
@@ -744,8 +941,22 @@
}
private static int compareSpecializationWithoutOrder(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
- if (m1.getSpecification() != m2.getSpecification()) {
- throw new UnsupportedOperationException("Cannot compare two specializations with different specifications.");
+ if (m1 == m2) {
+ return 0;
+ }
+
+ if (m1.isUninitialized() && !m2.isUninitialized()) {
+ return -1;
+ } else if (!m1.isUninitialized() && m2.isUninitialized()) {
+ return 1;
+ } else if (m1.isGeneric() && !m2.isGeneric()) {
+ return 1;
+ } else if (!m1.isGeneric() && m2.isGeneric()) {
+ return -1;
+ }
+
+ if (m1.getTemplate() != m2.getTemplate()) {
+ throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
}
int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType());
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java Wed Mar 13 20:05:30 2013 +0100
@@ -61,8 +61,7 @@
}
for (ActualParameter param : getParameters()) {
- ParameterSpec paramSpec = param.getSpecification();
- ActualParameter specializationParam = specialization.findParameter(paramSpec.getName());
+ ActualParameter specializationParam = specialization.findParameter(param.getName());
if (!Utils.typeEquals(param.getActualType(), specializationParam.getActualType())) {
return false;
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -48,14 +48,8 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- String shortCircuitValue = Utils.getAnnotationValueString(mirror, "value");
-
- if (!shortCircuitValues.contains(shortCircuitValue)) {
- getContext().getLog().error(method, mirror, "Invalid short circuit value %s.", shortCircuitValue);
- return null;
- }
-
- return createDefaultMethodSpec(shortCircuitValue);
+ String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
+ return createDefaultMethodSpec(method, mirror, shortCircuitValue);
}
@Override
@@ -65,9 +59,12 @@
@Override
public ShortCircuitData create(TemplateMethod method) {
- String shortCircuitValue = Utils.getAnnotationValueString(method.getMarkerAnnotation(), "value");
- assert shortCircuitValue != null;
- assert shortCircuitValues.contains(shortCircuitValue);
+ String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value");
+
+ if (!shortCircuitValues.contains(shortCircuitValue)) {
+ method.addError("Invalid short circuit value %s.", shortCircuitValue);
+ }
+
return new ShortCircuitData(method, shortCircuitValue);
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Wed Mar 13 20:05:30 2013 +0100
@@ -22,7 +22,10 @@
*/
package com.oracle.truffle.codegen.processor.node;
+import java.util.*;
+
import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.template.*;
public class SpecializationData extends TemplateMethod {
@@ -30,13 +33,13 @@
private final int order;
private final boolean generic;
private final boolean uninitialized;
- private final SpecializationThrowsData[] exceptions;
- private SpecializationGuardData[] guards;
- private ShortCircuitData[] shortCircuits;
+ private final List exceptions;
+ private List guards;
+ private List shortCircuits;
private boolean useSpecializationsForGeneric = true;
private NodeData node;
- public SpecializationData(TemplateMethod template, int order, SpecializationThrowsData[] exceptions) {
+ public SpecializationData(TemplateMethod template, int order, List exceptions) {
super(template);
this.order = order;
this.generic = false;
@@ -53,8 +56,40 @@
this.order = Specialization.DEFAULT_ORDER;
this.generic = generic;
this.uninitialized = uninitialized;
- this.exceptions = new SpecializationThrowsData[0];
- this.guards = new SpecializationGuardData[0];
+ this.exceptions = Collections.emptyList();
+ this.guards = new ArrayList<>();
+ }
+
+ @Override
+ protected List findChildContainers() {
+ List sinks = new ArrayList<>();
+ if (exceptions != null) {
+ sinks.addAll(exceptions);
+ }
+ if (guards != null) {
+ sinks.addAll(guards);
+ }
+ return sinks;
+ }
+
+ public boolean hasRewrite(ProcessorContext context) {
+ if (!getExceptions().isEmpty()) {
+ return true;
+ }
+ if (!getGuards().isEmpty()) {
+ return true;
+ }
+ for (ActualParameter parameter : getParameters()) {
+ NodeFieldData field = getNode().findField(parameter.getSpecification().getName());
+ if (field == null) {
+ continue;
+ }
+ ExecutableTypeData type = field.getNodeData().findExecutableType(parameter.getActualTypeData(field.getNodeData().getTypeSystem()));
+ if (type.hasUnexpectedValue(context)) {
+ return true;
+ }
+ }
+ return false;
}
public NodeData getNode() {
@@ -65,7 +100,7 @@
this.node = node;
}
- public void setGuards(SpecializationGuardData[] guards) {
+ public void setGuards(List guards) {
this.guards = guards;
}
@@ -81,19 +116,19 @@
return uninitialized;
}
- public SpecializationThrowsData[] getExceptions() {
+ public List getExceptions() {
return exceptions;
}
- public SpecializationGuardData[] getGuards() {
+ public List getGuards() {
return guards;
}
- public void setShortCircuits(ShortCircuitData[] shortCircuits) {
+ public void setShortCircuits(List shortCircuits) {
this.shortCircuits = shortCircuits;
}
- public ShortCircuitData[] getShortCircuits() {
+ public List getShortCircuits() {
return shortCircuits;
}
@@ -106,10 +141,10 @@
}
public SpecializationData findNextSpecialization() {
- SpecializationData[] specializations = node.getSpecializations();
- for (int i = 0; i < specializations.length - 1; i++) {
- if (specializations[i] == this) {
- return specializations[i + 1];
+ List specializations = node.getSpecializations();
+ for (int i = 0; i < specializations.size() - 1; i++) {
+ if (specializations.get(i) == this) {
+ return specializations.get(i + 1);
}
}
return null;
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationGuardData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationGuardData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationGuardData.java Wed Mar 13 20:05:30 2013 +0100
@@ -22,20 +22,42 @@
*/
package com.oracle.truffle.codegen.processor.node;
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.codegen.processor.template.*;
import com.oracle.truffle.codegen.processor.typesystem.*;
-public class SpecializationGuardData {
+public class SpecializationGuardData extends MessageContainer {
+ private final SpecializationData specialization;
+ private final AnnotationValue value;
private final String guardMethod;
private final boolean onSpecialization;
private final boolean onExecution;
private GuardData guardDeclaration;
- public SpecializationGuardData(String guardMethod, boolean onSpecialization, boolean onExecution) {
+ public SpecializationGuardData(SpecializationData specialization, AnnotationValue value, String guardMethod, boolean onSpecialization, boolean onExecution) {
+ this.specialization = specialization;
this.guardMethod = guardMethod;
this.onSpecialization = onSpecialization;
this.onExecution = onExecution;
+ this.value = value;
+ }
+
+ @Override
+ public Element getMessageElement() {
+ return specialization.getMessageElement();
+ }
+
+ @Override
+ public AnnotationMirror getMessageAnnotation() {
+ return specialization.getMessageAnnotation();
+ }
+
+ @Override
+ public AnnotationValue getMessageAnnotationValue() {
+ return value;
}
public String getGuardMethod() {
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.codegen.processor.node;
+
+import com.oracle.truffle.codegen.processor.template.*;
+
+public class SpecializationListenerData extends TemplateMethod {
+
+ public SpecializationListenerData(TemplateMethod method) {
+ super(method);
+ }
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -30,18 +30,15 @@
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.template.*;
-public class SpecializationListenerParser extends MethodParser {
-
- private final MethodSpec specification;
+public class SpecializationListenerParser extends MethodParser {
public SpecializationListenerParser(ProcessorContext context, NodeData node) {
super(context, node);
- this.specification = createDefaultMethodSpec(null);
}
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- return specification;
+ return createDefaultMethodSpec(method, mirror, null);
}
@Override
@@ -50,8 +47,8 @@
}
@Override
- public TemplateMethod create(TemplateMethod method) {
- return method;
+ public SpecializationListenerData create(TemplateMethod method) {
+ return new SpecializationListenerData(method);
}
@Override
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -35,16 +35,13 @@
public class SpecializationMethodParser extends MethodParser {
- private final MethodSpec specification;
-
public SpecializationMethodParser(ProcessorContext context, NodeData operation) {
super(context, operation);
- this.specification = createDefaultMethodSpec(null);
}
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- return specification;
+ return createDefaultMethodSpec(method, mirror, null);
}
@Override
@@ -58,27 +55,24 @@
}
private SpecializationData parseSpecialization(TemplateMethod method) {
- int order = Utils.getAnnotationValueInt(method.getMarkerAnnotation(), "order");
+ int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order");
if (order < 0 && order != Specialization.DEFAULT_ORDER) {
- getContext().getLog().error(method.getMethod(), method.getMarkerAnnotation(), "Invalid order attribute %d. The value must be >= 0 or the default value.");
+ method.addError("Invalid order attribute %d. The value must be >= 0 or the default value.");
return null;
}
- List exceptionDefs = Utils.collectAnnotations(getContext(), method.getMarkerAnnotation(), "exceptions", method.getMethod(), SpecializationThrows.class);
- SpecializationThrowsData[] exceptionData = new SpecializationThrowsData[exceptionDefs.size()];
- for (int i = 0; i < exceptionData.length; i++) {
- AnnotationMirror mirror = exceptionDefs.get(i);
- TypeMirror javaClass = Utils.getAnnotationValueType(mirror, "javaClass");
- String transitionTo = Utils.getAnnotationValueString(mirror, "transitionTo");
- exceptionData[i] = new SpecializationThrowsData(mirror, javaClass, transitionTo);
-
- if (!Utils.canThrowType(method.getMethod().getThrownTypes(), javaClass)) {
- getContext().getLog().error(method.getMethod(), "Method must specify a throws clause with the exception type '%s'.", Utils.getQualifiedName(javaClass));
- return null;
+ AnnotationValue rewriteValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn");
+ List exceptionTypes = Utils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn");
+ List exceptionData = new ArrayList<>();
+ for (TypeMirror exceptionType : exceptionTypes) {
+ SpecializationThrowsData throwsData = new SpecializationThrowsData(method.getMarkerAnnotation(), rewriteValue, exceptionType);
+ if (!Utils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) {
+ throwsData.addError("Method must specify a throws clause with the exception type '%s'.", Utils.getQualifiedName(exceptionType));
}
+ exceptionData.add(throwsData);
}
- Arrays.sort(exceptionData, new Comparator() {
+ Collections.sort(exceptionData, new Comparator() {
@Override
public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) {
@@ -87,26 +81,19 @@
});
SpecializationData specialization = new SpecializationData(method, order, exceptionData);
boolean valid = true;
- List guardDefs = Utils.collectAnnotations(getContext(), method.getMarkerAnnotation(), "guards", method.getMethod(), SpecializationGuard.class);
- SpecializationGuardData[] guardData = new SpecializationGuardData[guardDefs.size()];
- for (int i = 0; i < guardData.length; i++) {
- AnnotationMirror guardMirror = guardDefs.get(i);
- String guardMethod = Utils.getAnnotationValueString(guardMirror, "methodName");
- boolean onSpecialization = Utils.getAnnotationValueBoolean(guardMirror, "onSpecialization");
- boolean onExecution = Utils.getAnnotationValueBoolean(guardMirror, "onExecution");
+ AnnotationValue guardsValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "guards");
+ List guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
+ List guardData = new ArrayList<>(guardDefs.size());
+ for (int i = 0; i < guardDefs.size(); i++) {
+ String guardMethod = guardDefs.get(i);
- if (!onSpecialization && !onExecution) {
- String message = "Either onSpecialization, onExecution or both must be enabled.";
- getContext().getLog().error(method.getMethod(), guardMirror, message);
- valid = false;
- continue;
- }
+ SpecializationGuardData assignedGuard = new SpecializationGuardData(specialization, guardsValue, guardMethod, true, true);
+
+ guardData.add(assignedGuard);
- guardData[i] = new SpecializationGuardData(guardMethod, onSpecialization, onExecution);
-
- GuardData compatibleGuard = matchSpecializationGuard(guardMirror, specialization, guardData[i]);
+ GuardData compatibleGuard = matchSpecializationGuard(specialization, assignedGuard);
if (compatibleGuard != null) {
- guardData[i].setGuardDeclaration(compatibleGuard);
+ assignedGuard.setGuardDeclaration(compatibleGuard);
} else {
valid = false;
}
@@ -121,7 +108,7 @@
return specialization;
}
- private GuardData matchSpecializationGuard(AnnotationMirror mirror, SpecializationData specialization, SpecializationGuardData specializationGuard) {
+ private GuardData matchSpecializationGuard(SpecializationData specialization, SpecializationGuardData specializationGuard) {
List foundGuards = getNode().findGuards(specializationGuard.getGuardMethod());
GuardData compatibleGuard = null;
@@ -142,16 +129,14 @@
}
List typeDefs = createTypeDefinitions(returnTypeSpec, expectedParameterSpecs);
String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs, typeDefs);
- AnnotationValue value = Utils.getAnnotationValue(mirror, "methodName");
- getContext().getLog().error(specialization.getMethod(), mirror, value, "No guard with signature '%s' found in type system.", expectedSignature);
- return null;
+ specializationGuard.addError("No guard with signature '%s' found in type system.", expectedSignature);
}
return compatibleGuard;
}
private static boolean isGuardCompatible(SpecializationData specialization, GuardData guard) {
- Iterator guardParameters = Arrays.asList(guard.getParameters()).iterator();
+ Iterator guardParameters = guard.getParameters().iterator();
for (ActualParameter param : specialization.getParameters()) {
if (param.getSpecification().isOptional()) {
continue;
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java Wed Mar 13 20:05:30 2013 +0100
@@ -25,23 +25,40 @@
import javax.lang.model.element.*;
import javax.lang.model.type.*;
-public class SpecializationThrowsData {
+import com.oracle.truffle.codegen.processor.template.*;
+public class SpecializationThrowsData extends MessageContainer {
+
+ private final AnnotationValue annotationValue;
private final AnnotationMirror annotationMirror;
private final TypeMirror javaClass;
- private final String transitionTo;
private SpecializationData specialization;
- public SpecializationThrowsData(AnnotationMirror annotationMirror, TypeMirror javaClass, String transitionTo) {
+ public SpecializationThrowsData(AnnotationMirror annotationMirror, AnnotationValue value, TypeMirror javaClass) {
this.annotationMirror = annotationMirror;
+ this.annotationValue = value;
this.javaClass = javaClass;
- this.transitionTo = transitionTo;
}
void setSpecialization(SpecializationData specialization) {
this.specialization = specialization;
}
+ @Override
+ public Element getMessageElement() {
+ return specialization.getMessageElement();
+ }
+
+ @Override
+ public AnnotationMirror getMessageAnnotation() {
+ return annotationMirror;
+ }
+
+ @Override
+ public AnnotationValue getMessageAnnotationValue() {
+ return annotationValue;
+ }
+
public TypeMirror getJavaClass() {
return javaClass;
}
@@ -54,16 +71,7 @@
return annotationMirror;
}
- public String getTransitionToName() {
- return transitionTo;
- }
-
public SpecializationData getTransitionTo() {
- for (SpecializationData s : specialization.getNode().getSpecializations()) {
- if (s.getMethodName().equals(transitionTo)) {
- return s;
- }
- }
- return null;
+ return specialization.findNextSpecialization();
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java Wed Mar 13 20:05:30 2013 +0100
@@ -31,10 +31,33 @@
private final ParameterSpec specification;
private final TypeMirror actualType;
private TemplateMethod method;
+ private final String name;
+ private final int index;
+ private final boolean implicit;
- public ActualParameter(ParameterSpec specification, TypeMirror actualType) {
+ public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean implicit) {
this.specification = specification;
this.actualType = actualType;
+
+ this.index = index;
+ this.implicit = implicit;
+ String valueName = specification.getName() + "Value";
+ if (specification.isIndexed()) {
+ valueName = valueName + index;
+ }
+ this.name = valueName;
+ }
+
+ public boolean isHidden() {
+ return implicit;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getName() {
+ return name;
}
void setMethod(TemplateMethod method) {
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java Wed Mar 13 20:05:30 2013 +0100
@@ -128,6 +128,10 @@
CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class));
generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
+ if (model.getTemplateMethodName() != null) {
+ generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(model.getTemplateMethodName()));
+ }
+
clazz.addAnnotationMirror(generatedByAnnotation);
context.registerType(model.getTemplateType(), clazz.asType());
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java Wed Mar 13 20:05:30 2013 +0100
@@ -0,0 +1,180 @@
+/*
+ * 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.codegen.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.codegen.processor.*;
+
+public abstract class MessageContainer {
+
+ private final List messages = new ArrayList<>();
+
+ public final void addWarning(String text, Object... params) {
+ getMessages().add(new Message(this, String.format(text, params), Kind.WARNING));
+ }
+
+ public final void addError(String text, Object... params) {
+ getMessages().add(new Message(this, String.format(text, params), Kind.ERROR));
+ }
+
+ protected List findChildContainers() {
+ return Collections.emptyList();
+ }
+
+ public abstract Element getMessageElement();
+
+ public final void emitMessages(TypeElement baseElement, Log log) {
+ emitMessagesImpl(baseElement, log, new HashSet());
+ }
+
+ private void emitMessagesImpl(TypeElement baseElement, Log log, Set visitedSinks) {
+ for (Message message : getMessages()) {
+ emitDefault(baseElement, log, message);
+ }
+
+ for (MessageContainer sink : findChildContainers()) {
+ if (visitedSinks.contains(sink)) {
+ return;
+ }
+
+ visitedSinks.add(sink);
+ sink.emitMessagesImpl(baseElement, log, visitedSinks);
+ }
+ }
+
+ private void emitDefault(TypeElement baseType, Log log, Message message) {
+ if (Utils.typeEquals(baseType.asType(), Utils.findRootEnclosingType(getMessageElement()).asType()) && this == message.getOriginalContainer()) {
+ log.message(message.getKind(), getMessageElement(), getMessageAnnotation(), getMessageAnnotationValue(), message.getText());
+ } else {
+ MessageContainer original = message.getOriginalContainer();
+ log.message(message.getKind(), baseType, null, null, wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()));
+ }
+ }
+
+ private static String wrapText(Element element, AnnotationMirror mirror, String text) {
+ StringBuilder b = new StringBuilder();
+ if (element != null) {
+ b.append("Element " + element.toString());
+ }
+ if (mirror != null) {
+ b.append(" at annotation @" + Utils.getSimpleName(mirror.getAnnotationType()));
+ }
+
+ if (b.length() > 0) {
+ b.append(" is erroneous: ").append(text);
+ return b.toString();
+ } else {
+ return text;
+ }
+ }
+
+ public AnnotationMirror getMessageAnnotation() {
+ return null;
+ }
+
+ public AnnotationValue getMessageAnnotationValue() {
+ return null;
+ }
+
+ public final boolean hasErrors() {
+ return hasErrorsImpl(new HashSet());
+ }
+
+ public final List collectMessages() {
+ List collectedMessages = new ArrayList<>();
+ collectMessagesImpl(collectedMessages, new HashSet());
+ return collectedMessages;
+ }
+
+ private void collectMessagesImpl(List collectedMessages, Set visitedSinks) {
+ collectedMessages.addAll(getMessages());
+ for (MessageContainer sink : findChildContainers()) {
+ if (visitedSinks.contains(sink)) {
+ return;
+ }
+
+ visitedSinks.add(sink);
+ sink.collectMessagesImpl(collectedMessages, visitedSinks);
+ }
+ }
+
+ private boolean hasErrorsImpl(Set visitedSinks) {
+ for (Message msg : getMessages()) {
+ if (msg.getKind() == Kind.ERROR) {
+ return true;
+ }
+ }
+ for (MessageContainer sink : findChildContainers()) {
+ if (visitedSinks.contains(sink)) {
+ return false;
+ }
+
+ visitedSinks.add(sink);
+
+ if (sink.hasErrorsImpl(visitedSinks)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List getMessages() {
+ return messages;
+ }
+
+ public static final class Message {
+
+ private final MessageContainer originalContainer;
+ private final String text;
+ private final Kind kind;
+
+ public Message(MessageContainer originalContainer, String text, Kind kind) {
+ this.originalContainer = originalContainer;
+ this.text = text;
+ this.kind = kind;
+ }
+
+ public MessageContainer getOriginalContainer() {
+ return originalContainer;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public Kind getKind() {
+ return kind;
+ }
+
+ @Override
+ public String toString() {
+ return kind + ": " + text;
+ }
+
+ }
+
+}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java Wed Mar 13 20:05:30 2013 +0100
@@ -24,16 +24,25 @@
import java.util.*;
+import javax.lang.model.type.*;
+
public class MethodSpec {
+ private final List implicitTypes;
+
private final ParameterSpec returnType;
private final List parameters;
- public MethodSpec(ParameterSpec returnType, List parameters) {
+ public MethodSpec(List prefixTypes, ParameterSpec returnType, List parameters) {
+ this.implicitTypes = prefixTypes;
this.returnType = returnType;
this.parameters = parameters;
}
+ public List getImplicitTypes() {
+ return implicitTypes;
+ }
+
public ParameterSpec getReturnType() {
return returnType;
}
@@ -41,4 +50,14 @@
public List getParameters() {
return parameters;
}
+
+ public ParameterSpec findParameterSpec(String name) {
+ for (ParameterSpec spec : parameters) {
+ if (spec.getName().equals(name)) {
+ return spec;
+ }
+ }
+ return null;
+ }
+
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Wed Mar 13 20:05:30 2013 +0100
@@ -37,11 +37,12 @@
}
private final String name;
- private final TypeMirror[] allowedTypes;
+ private final List allowedTypes;
private final boolean optional;
- private final Cardinality cardinality;
+ private Cardinality cardinality;
+ private boolean indexed;
- public ParameterSpec(String name, TypeMirror[] allowedTypes, boolean optional, Cardinality cardinality) {
+ public ParameterSpec(String name, List allowedTypes, boolean optional, Cardinality cardinality) {
this.allowedTypes = allowedTypes;
this.name = name;
this.optional = optional;
@@ -50,7 +51,7 @@
/** Type constructor. */
public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional) {
- this(name, new TypeMirror[]{singleFixedType}, optional, Cardinality.ONE);
+ this(name, Arrays.asList(singleFixedType), optional, Cardinality.ONE);
}
/** Type system value constructor. */
@@ -63,7 +64,19 @@
this(name, nodeTypeMirrors(nodeData), optional, cardinality);
}
- private static TypeMirror[] nodeTypeMirrors(NodeData nodeData) {
+ public boolean isIndexed() {
+ return indexed;
+ }
+
+ public void setIndexed(boolean indexed) {
+ this.indexed = indexed;
+ }
+
+ public void setCardinality(Cardinality cardinality) {
+ this.cardinality = cardinality;
+ }
+
+ private static List nodeTypeMirrors(NodeData nodeData) {
Set typeMirrors = new LinkedHashSet<>();
for (ExecutableTypeData typeData : nodeData.getExecutableTypes()) {
@@ -72,7 +85,7 @@
typeMirrors.add(nodeData.getTypeSystem().getGenericType());
- return typeMirrors.toArray(new TypeMirror[typeMirrors.size()]);
+ return new ArrayList<>(typeMirrors);
}
public final String getName() {
@@ -87,13 +100,12 @@
return cardinality;
}
- public TypeMirror[] getAllowedTypes() {
+ public List getAllowedTypes() {
return allowedTypes;
}
public boolean matches(TypeMirror actualType) {
- for (int i = 0; i < allowedTypes.length; i++) {
- TypeMirror mirror = allowedTypes[i];
+ for (TypeMirror mirror : allowedTypes) {
if (Utils.typeEquals(actualType, mirror)) {
return true;
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java Wed Mar 13 20:05:30 2013 +0100
@@ -29,18 +29,34 @@
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.api.element.*;
-public abstract class Template {
+public abstract class Template extends MessageContainer {
private final TypeElement templateType;
+ private final String templateMethodName;
private final AnnotationMirror annotation;
private List extends WritableElement> extensionElements;
- public Template(TypeElement templateType, AnnotationMirror annotation) {
+ public Template(TypeElement templateType, String templateMethodName, AnnotationMirror annotation) {
this.templateType = templateType;
+ this.templateMethodName = templateMethodName;
this.annotation = annotation;
}
+ @Override
+ public Element getMessageElement() {
+ return templateType;
+ }
+
+ @Override
+ protected List findChildContainers() {
+ return Collections.emptyList();
+ }
+
+ public String getTemplateMethodName() {
+ return templateMethodName;
+ }
+
public TypeElement getTemplateType() {
return templateType;
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Wed Mar 13 20:05:30 2013 +0100
@@ -22,24 +22,32 @@
*/
package com.oracle.truffle.codegen.processor.template;
+import java.util.*;
+
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
-public class TemplateMethod {
+import com.oracle.truffle.codegen.processor.*;
+public class TemplateMethod extends MessageContainer {
+
+ private String id;
private final Template template;
private final MethodSpec specification;
private final ExecutableElement method;
private final AnnotationMirror markerAnnotation;
private final ActualParameter returnType;
- private final ActualParameter[] parameters;
+ private final List parameters;
- public TemplateMethod(Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType, ActualParameter[] parameters) {
+ public TemplateMethod(String id, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType,
+ List parameters) {
this.template = template;
this.specification = specification;
this.method = method;
this.markerAnnotation = markerAnnotation;
this.returnType = returnType;
this.parameters = parameters;
+ this.id = id;
if (parameters != null) {
for (ActualParameter param : parameters) {
@@ -49,7 +57,31 @@
}
public TemplateMethod(TemplateMethod method) {
- this(method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters);
+ this(method.id, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters);
+ getMessages().addAll(method.getMessages());
+ }
+
+ @Override
+ public Element getMessageElement() {
+ return method;
+ }
+
+ @Override
+ public AnnotationMirror getMessageAnnotation() {
+ return markerAnnotation;
+ }
+
+ @Override
+ protected List findChildContainers() {
+ return Collections.emptyList();
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
}
public Template getTemplate() {
@@ -64,34 +96,50 @@
return returnType;
}
- public ActualParameter[] getParameters() {
+ public List getParameters() {
return parameters;
}
public ActualParameter findParameter(String valueName) {
for (ActualParameter param : getParameters()) {
- if (param.getSpecification().getName().equals(valueName)) {
+ if (param.getName().equals(valueName)) {
return param;
}
}
return null;
}
+ public List getReturnTypeAndParameters() {
+ List allParameters = new ArrayList<>(getParameters().size() + 1);
+ allParameters.add(getReturnType());
+ allParameters.addAll(getParameters());
+ return Collections.unmodifiableList(allParameters);
+ }
+
public ActualParameter findParameter(ParameterSpec spec) {
for (ActualParameter param : getParameters()) {
- if (param.getSpecification() == spec) {
+ if (param.getSpecification().getName().equals(spec.getName())) {
return param;
}
}
return null;
}
+ public boolean canBeAccessedByInstanceOf(TypeMirror type) {
+ TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType();
+ return Utils.isAssignable(type, methodType) || Utils.isAssignable(methodType, type);
+ }
+
public ExecutableElement getMethod() {
return method;
}
public String getMethodName() {
- return getMethod().getSimpleName().toString();
+ if (getMethod() != null) {
+ return getMethod().getSimpleName().toString();
+ } else {
+ return "$synthetic";
+ }
}
public AnnotationMirror getMarkerAnnotation() {
@@ -100,7 +148,7 @@
@Override
public String toString() {
- return getClass().getSimpleName() + " [method = " + method + "]";
+ return "id = " + getId() + ", " + getClass().getSimpleName() + " [method = " + getMethod() + "]";
}
public ActualParameter getPreviousParam(ActualParameter searchParam) {
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -31,6 +31,7 @@
import javax.lang.model.type.*;
import javax.lang.model.util.*;
+import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
@@ -95,13 +96,14 @@
mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
}
- if (method.getModifiers().contains(Modifier.PRIVATE)) {
- getContext().getLog().error(method, "Method must not be private.");
+ E parsedMethod = parse(method, mirror);
+
+ if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) {
+ parsedMethod.addError("Method must not be private.");
valid = false;
continue;
}
- E parsedMethod = parse(method, mirror);
if (parsedMethod != null) {
parsedMethods.add(parsedMethod);
} else {
@@ -120,108 +122,126 @@
return null;
}
+ String id = method.getSimpleName().toString();
+ AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class);
+ if (idAnnotation != null) {
+ id = Utils.getAnnotationValue(String.class, idAnnotation, "value");
+ }
+
List typeDefs = createTypeDefinitions(methodSpecification.getReturnType(), methodSpecification.getParameters());
ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
List parameterSpecs = new ArrayList<>();
parameterSpecs.addAll(methodSpecification.getParameters());
- ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template);
+ ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false);
if (returnTypeMirror == null) {
- if (isEmitErrors()) {
+ if (emitErrors) {
+ E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()));
String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
String actualReturnType = Utils.getSimpleName(method.getReturnType());
String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
+ invalidMethod.addError(message);
+ return invalidMethod;
+ } else {
+ return null;
+ }
+ }
- context.getLog().error(method, annotation, message);
+ List parameterTypes = new ArrayList<>();
+ parameterTypes.addAll(methodSpecification.getImplicitTypes());
+ for (VariableElement var : method.getParameters()) {
+ parameterTypes.add(var.asType());
+ }
+
+ List parameters = parseParameters(parameterTypes, parameterSpecs, methodSpecification.getImplicitTypes().size());
+ if (parameters == null) {
+ if (isEmitErrors()) {
+ E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()));
+ String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(methodSpecification, method),
+ createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
+ invalidMethod.addError(message);
+ return invalidMethod;
+ } else {
+ return null;
}
- return null;
}
- Iterator extends VariableElement> variableIterator = method.getParameters().iterator();
+ return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters));
+ }
+
+ private static String createActualSignature(MethodSpec spec, ExecutableElement method) {
+ List types = new ArrayList<>();
+ for (TypeMirror implicitType : spec.getImplicitTypes()) {
+ types.add("implicit " + Utils.getSimpleName(implicitType));
+ }
+ for (VariableElement var : method.getParameters()) {
+ types.add(Utils.getSimpleName(var.asType()));
+ }
+
+ StringBuilder b = new StringBuilder("(");
+ for (Iterator iterator = types.iterator(); iterator.hasNext();) {
+ b.append(iterator.next());
+ if (iterator.hasNext()) {
+ b.append(", ");
+ }
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ private List parseParameters(List types, List parameterSpecs, int hiddenCount) {
+ Iterator extends TypeMirror> parameterIterator = types.iterator();
Iterator extends ParameterSpec> specificationIterator = parameterSpecs.iterator();
- List resolvedMirrors = new ArrayList<>();
- VariableElement parameter = null;
- ParameterSpec specification = null;
- while (specificationIterator.hasNext() || specification != null) {
- if (specification == null) {
- specification = specificationIterator.next();
- }
-
- if (parameter == null && variableIterator.hasNext()) {
- parameter = variableIterator.next();
- }
-
- if (parameter == null) {
- if (specification.getCardinality() == Cardinality.MULTIPLE) {
- specification = null;
- continue;
- } else if (!specification.isOptional()) {
- if (isEmitErrors()) {
- // non option type specification found -> argument missing
- String expectedType = createTypeSignature(specification, typeDefs, false);
-
- String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
- createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
+ TypeMirror parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
+ ParameterSpec specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
- context.getLog().error(method, message);
- }
- return null;
- } else {
- // specification is optional -> continue
- specification = null;
+ int globalParameterIndex = 0;
+ int specificationParameterIndex = 0;
+ List resolvedParameters = new ArrayList<>();
+ while (parameter != null || specification != null) {
+ if (parameter == null || specification == null) {
+ if (specification != null && (specification.isOptional() || specification.getCardinality() == Cardinality.MULTIPLE)) {
+ specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
+ specificationParameterIndex = 0;
continue;
}
- }
-
- ActualParameter resolvedMirror = resolveTypeMirror(specification, parameter.asType(), template);
-
- if (resolvedMirror == null) {
- if (specification.isOptional()) {
- specification = null;
- continue;
- }
-
- if (isEmitErrors()) {
- String expectedReturnType = createTypeSignature(specification, typeDefs, false);
- String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
-
- String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
- createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
-
- context.getLog().error(parameter, message);
- }
return null;
}
- resolvedMirrors.add(resolvedMirror);
- parameter = null; // consume parameter
+ boolean hidden = globalParameterIndex < hiddenCount;
+ ActualParameter resolvedParameter = matchParameter(specification, parameter, template, specificationParameterIndex, hidden);
+ if (resolvedParameter == null) {
+ // mismatch
+ if (specification.isOptional()) {
+ specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
+ specificationParameterIndex = 0;
+ } else {
+ return null;
+ }
+ } else {
+ resolvedParameters.add(resolvedParameter);
- if (specification.getCardinality() != Cardinality.MULTIPLE) {
- specification = null;
+ // match
+ if (specification.getCardinality() == Cardinality.ONE) {
+ parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
+ specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
+ globalParameterIndex++;
+ specificationParameterIndex = 0;
+ } else if (specification.getCardinality() == Cardinality.MULTIPLE) {
+ parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
+ globalParameterIndex++;
+ specificationParameterIndex++;
+ }
}
}
-
- if (variableIterator.hasNext()) {
- parameter = variableIterator.next();
- if (isEmitErrors()) {
- String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
- String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
- createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
-
- context.getLog().error(parameter, message);
- }
- return null;
- }
-
- ActualParameter[] paramMirrors = resolvedMirrors.toArray(new ActualParameter[resolvedMirrors.size()]);
- return create(new TemplateMethod(template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors));
+ return resolvedParameters;
}
- private ActualParameter resolveTypeMirror(ParameterSpec specification, TypeMirror mirror, Template typeSystem) {
+ private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template typeSystem, int index, boolean hidden) {
TypeMirror resolvedType = mirror;
if (hasError(resolvedType)) {
resolvedType = context.resolveNotYetCompiledType(mirror, typeSystem);
@@ -230,7 +250,7 @@
if (!specification.matches(resolvedType)) {
return null;
}
- return new ActualParameter(specification, resolvedType);
+ return new ActualParameter(specification, resolvedType, index, hidden);
}
protected List createTypeDefinitions(ParameterSpec returnType, List extends ParameterSpec> parameters) {
@@ -242,12 +262,12 @@
int defIndex = 0;
for (ParameterSpec spec : allParams) {
- TypeMirror[] allowedTypes = spec.getAllowedTypes();
- TypeMirror[] types = spec.getAllowedTypes();
- if (types != null && allowedTypes.length > 1) {
+ List allowedTypes = spec.getAllowedTypes();
+ List types = spec.getAllowedTypes();
+ if (types != null && allowedTypes.size() > 1) {
TypeDef foundDef = null;
for (TypeDef def : typeDefs) {
- if (Arrays.equals(allowedTypes, def.getTypes())) {
+ if (allowedTypes.equals(def.getTypes())) {
foundDef = def;
break;
}
@@ -267,11 +287,11 @@
protected static class TypeDef {
- private final TypeMirror[] types;
+ private final List types;
private final String name;
private final List parameters = new ArrayList<>();
- public TypeDef(TypeMirror[] types, String name) {
+ public TypeDef(List types, String name) {
this.types = types;
this.name = name;
}
@@ -280,7 +300,7 @@
return parameters;
}
- public TypeMirror[] getTypes() {
+ public List getTypes() {
return types;
}
@@ -349,7 +369,7 @@
private static String createTypeSignature(ParameterSpec spec, List typeDefs, boolean typeOnly) {
StringBuilder builder = new StringBuilder();
- if (spec.getAllowedTypes().length > 1) {
+ if (spec.getAllowedTypes().size() > 1) {
TypeDef foundTypeDef = null;
for (TypeDef typeDef : typeDefs) {
if (typeDef.getParameters().contains(spec)) {
@@ -360,8 +380,8 @@
if (foundTypeDef != null) {
builder.append("<" + foundTypeDef.getName() + ">");
}
- } else if (spec.getAllowedTypes().length == 1) {
- builder.append(Utils.getSimpleName(spec.getAllowedTypes()[0]));
+ } else if (spec.getAllowedTypes().size() == 1) {
+ builder.append(Utils.getSimpleName(spec.getAllowedTypes().get(0)));
} else {
builder.append("void");
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -43,9 +43,8 @@
return extensionParser;
}
- protected boolean verifyExclusiveMethodAnnotation(TypeElement type, Class>... annotationTypes) {
- boolean valid = true;
- List methods = ElementFilter.methodsIn(type.getEnclosedElements());
+ protected void verifyExclusiveMethodAnnotation(Template template, Class>... annotationTypes) {
+ List methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements());
for (ExecutableElement method : methods) {
List foundAnnotations = new ArrayList<>();
for (int i = 0; i < annotationTypes.length; i++) {
@@ -61,34 +60,9 @@
annotationNames.add("@" + Utils.getSimpleName(mirror.getAnnotationType()));
}
- for (AnnotationMirror mirror : foundAnnotations) {
- context.getLog().error(method, mirror, "Non exclusive usage of annotations %s.", annotationNames);
- }
- valid = false;
+ template.addError("Non exclusive usage of annotations %s.", annotationNames);
}
}
- return valid;
- }
-
- protected boolean verifyTemplateType(TypeElement template, AnnotationMirror annotation) {
- // annotation type on class path!?
- boolean valid = true;
- TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName());
- if (annotationTypeElement == null) {
- log.error(template, annotation, "Required class " + getAnnotationType().getName() + " is not on the classpath.");
- valid = false;
- }
- if (template.getModifiers().contains(Modifier.PRIVATE)) {
- log.error(template, annotation, "The annotated class must have at least package protected visibility.");
- valid = false;
- }
-
- if (template.getModifiers().contains(Modifier.FINAL)) {
- log.error(template, annotation, "The annotated class must not be final.");
- valid = false;
- }
-
- return valid;
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java Wed Mar 13 20:05:30 2013 +0100
@@ -26,15 +26,8 @@
public class GuardData extends TemplateMethod {
- private final Template origin;
-
- public GuardData(TemplateMethod method, Template origin) {
+ public GuardData(TemplateMethod method) {
super(method);
- this.origin = origin;
- }
-
- public Template getOrigin() {
- return origin;
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -26,8 +26,8 @@
import java.util.*;
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
-import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.template.*;
import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
@@ -39,6 +39,8 @@
public GuardParser(ProcessorContext context, Template template, TypeSystemData typeSystem) {
super(context, template);
this.typeSystem = typeSystem;
+ setEmitErrors(false);
+ setParseNullOnError(false);
}
@Override
@@ -46,22 +48,22 @@
List specs = new ArrayList<>();
specs.add(new ParameterSpec("valueN", typeSystem, false, Cardinality.MULTIPLE));
ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false);
- return new MethodSpec(returnTypeSpec, specs);
+ return new MethodSpec(Collections. emptyList(), returnTypeSpec, specs);
}
@Override
public boolean isParsable(ExecutableElement method) {
- return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
+ return true;
}
@Override
public GuardData create(TemplateMethod method) {
- return new GuardData(method, template);
+ return new GuardData(method);
}
@Override
public Class extends Annotation> getAnnotationType() {
- return GuardCheck.class;
+ return null;
}
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -26,6 +26,7 @@
import java.util.*;
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.codegen.processor.*;
@@ -40,21 +41,21 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- TypeData targetType = findTypeByMethodName(method, mirror, "as");
+ TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "as");
if (targetType == null) {
return null;
}
List specs = new ArrayList<>();
specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE));
ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetType.getPrimitiveType(), false);
- MethodSpec spec = new MethodSpec(returnTypeSpec, specs);
+ MethodSpec spec = new MethodSpec(Collections. emptyList(), returnTypeSpec, specs);
return spec;
}
@Override
public TypeCastData create(TemplateMethod method) {
- TypeData targetType = findTypeByMethodName(method.getMethod(), method.getMarkerAnnotation(), "as");
- ActualParameter parameter = method.findParameter("value");
+ TypeData targetType = findTypeByMethodName(method, "as");
+ ActualParameter parameter = method.findParameter("valueValue");
return new TypeCastData(method, parameter.getActualTypeData(getTypeSystem()), targetType);
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java Wed Mar 13 20:05:30 2013 +0100
@@ -26,6 +26,7 @@
import java.util.*;
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.codegen.processor.*;
@@ -40,22 +41,22 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- TypeData targetType = findTypeByMethodName(method, mirror, "is");
+ TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "is");
if (targetType == null) {
return null;
}
List specs = new ArrayList<>();
specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE));
ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false);
- MethodSpec spec = new MethodSpec(returnTypeSpec, specs);
+ MethodSpec spec = new MethodSpec(Collections. emptyList(), returnTypeSpec, specs);
return spec;
}
@Override
public TypeCheckData create(TemplateMethod method) {
- TypeData checkedType = findTypeByMethodName(method.getMethod(), method.getMarkerAnnotation(), "is");
+ TypeData checkedType = findTypeByMethodName(method, "is");
assert checkedType != null;
- ActualParameter parameter = method.findParameter("value");
+ ActualParameter parameter = method.findParameter("valueValue");
assert parameter != null;
return new TypeCheckData(method, checkedType, parameter.getActualTypeData(getTypeSystem()));
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Wed Mar 13 20:05:30 2013 +0100
@@ -30,21 +30,38 @@
import com.oracle.truffle.codegen.processor.*;
import com.oracle.truffle.codegen.processor.template.*;
-public class TypeData extends Template {
+public class TypeData extends MessageContainer {
- protected TypeSystemData typeSystem;
+ private final TypeSystemData typeSystem;
+ private final AnnotationValue annotationValue;
private final TypeMirror primitiveType;
private final TypeMirror boxedType;
private final List typeCasts = new ArrayList<>();
private final List typeChecks = new ArrayList<>();
- public TypeData(TypeElement templateType, AnnotationMirror annotation, TypeMirror primitiveType, TypeMirror boxedType) {
- super(templateType, annotation);
+ public TypeData(TypeSystemData typeSystem, AnnotationValue value, TypeMirror primitiveType, TypeMirror boxedType) {
+ this.typeSystem = typeSystem;
+ this.annotationValue = value;
this.primitiveType = primitiveType;
this.boxedType = boxedType;
}
+ @Override
+ public Element getMessageElement() {
+ return typeSystem.getMessageElement();
+ }
+
+ @Override
+ public AnnotationMirror getMessageAnnotation() {
+ return typeSystem.getMessageAnnotation();
+ }
+
+ @Override
+ public AnnotationValue getMessageAnnotationValue() {
+ return annotationValue;
+ }
+
void addTypeCast(TypeCastData typeCast) {
this.typeCasts.add(typeCast);
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Wed Mar 13 20:05:30 2013 +0100
@@ -167,8 +167,8 @@
CodeTreeBuilder builder = method.createBuilder();
builder.startReturn();
- if (typeSystem.getTypes().length > 0) {
- builder.typeLiteral(typeSystem.getTypes()[0].getBoxedType());
+ if (!typeSystem.getTypes().isEmpty()) {
+ builder.typeLiteral(typeSystem.getTypes().get(0).getBoxedType());
} else {
builder.null_();
}
diff -r 35267b295f74 -r d02ba214b7e6 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java Wed Mar 13 11:00:43 2013 -0700
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java Wed Mar 13 20:05:30 2013 +0100
@@ -32,35 +32,42 @@
public class TypeSystemData extends Template {
- private final TypeData[] types;
- private final TypeMirror[] primitiveTypeMirrors;
- private final TypeMirror[] boxedTypeMirrors;
+ private List types;
+ private List