# HG changeset patch
# User Christian Humer
# Date 1363084732 -3600
# Node ID edc414f52e2b32179ab6fcaec8d791d70bbd29b4
# Parent aad7e9f4f71c040d232e2411fa95b143152c3913# Parent 2c5df42999dd9236e31f5ff01c1033affdb96679
Merge.
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 2013 +0100
@@ -0,0 +1,158 @@
+/*
+ * 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ /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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java Tue Mar 12 11:38:52 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> getChildrenSignature();
+
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ /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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ /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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Tue Mar 12 11:38:52 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);
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Tue Mar 12 11:38:52 2013 +0100
@@ -495,7 +495,7 @@
}
public CodeTreeBuilder create() {
- return new CodeTreeBuilder(null);
+ return new CodeTreeBuilder(this);
}
public CodeTreeBuilder type(TypeMirror type) {
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -88,7 +88,7 @@
} 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);
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -51,7 +51,7 @@
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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -41,7 +41,7 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- return createDefaultMethodSpec(null);
+ return createDefaultMethodSpec(method, mirror, null);
}
@Override
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Tue Mar 12 11:38:52 2013 +0100
@@ -34,7 +34,7 @@
import com.oracle.truffle.api.codegen.*;
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.*;
import com.oracle.truffle.codegen.processor.template.*;
import com.oracle.truffle.codegen.processor.typesystem.*;
@@ -51,73 +51,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 +101,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 +113,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,15 +142,41 @@
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();
+
+ 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) {
@@ -182,7 +192,7 @@
if (prev == null || prev.isUninitialized()) {
return prefix;
} else {
- return prefix + specializationId(current);
+ return prefix + current.getId();
}
}
prev = current;
@@ -253,8 +263,7 @@
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) {
@@ -263,8 +272,8 @@
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 +285,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 +305,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 +350,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 +382,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);
}
/**
@@ -492,7 +503,7 @@
if (node.needsFactory()) {
createFactoryMethods(node, clazz, createVisibility);
- if (node.getSpecializations().length > 1) {
+ if (node.getSpecializations().size() > 1) {
clazz.add(createCreateSpecializedMethod(node, createVisibility));
}
@@ -515,6 +526,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 +577,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, "getChildrenSignature");
+ 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 +770,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 +852,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 +887,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 +904,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();
@@ -871,11 +930,11 @@
if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) {
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 +942,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 +955,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);
}
@@ -918,29 +977,29 @@
builder.startReturn().startCall(generatedGenericMethodName(next));
builder.string(THIS_NODE_LOCAL_VAR_NAME);
- addValueParameterNames(builder, next, null, true);
+ addValueParameterNames(builder, next, null, true, 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);
+ 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();
@@ -957,7 +1016,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 +1040,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 +1055,7 @@
}
if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) {
- buildSpecializeStateMethod(clazz, specialization);
+ buildSpecializeAndExecute(clazz, specialization);
}
}
@@ -1014,7 +1073,7 @@
CodeTree primaryExecuteCall = null;
CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder();
- buildExecute(executeBuilder, null, execType);
+ buildExecute(executeBuilder, null, null, execType);
primaryExecuteCall = executeBuilder.getRoot();
if (needsTry) {
@@ -1122,7 +1181,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 +1193,29 @@
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())) {
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());
+ startCallOperationMethod(builder, specialization.getNode().getGenericSpecialization(), false);
} else {
- startCallOperationMethod(builder, specialization);
+ startCallOperationMethod(builder, specialization, false);
}
- addValueParameterNames(builder, specialization, null, 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 +1227,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 +1242,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 +1303,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;
@@ -1296,14 +1340,14 @@
builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
ShortCircuitData shortCircuitData = specialization.getShortCircuits()[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 +1359,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 +1373,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 +1384,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 +1395,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 +1406,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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Tue Mar 12 11:38:52 2013 +0100
@@ -35,22 +35,59 @@
public class NodeData extends Template {
- private NodeData parent;
- private List declaredChildren;
+ private final String nodeId;
+ private NodeData declaringNode;
+ private List declaredChildren = new ArrayList<>();
private final TypeSystemData typeSystem;
+ private List fields;
+ private TypeMirror nodeType;
+ private ParameterSpec instanceParameterSpec;
- private NodeFieldData[] fields;
- private SpecializationData[] specializations;
- private TemplateMethod[] specializationListeners;
- private GuardData[] guards;
- private ExecutableTypeData[] executableTypes;
+ private List specializations;
+ private List specializationListeners;
+ private List guards;
+ private List executableTypes;
+ private List shortCircuits;
+
+ public NodeData(TypeElement type, TypeSystemData typeSystem, String id) {
+ super(type, null, null);
+ this.nodeId = id;
+ this.typeSystem = typeSystem;
+ }
- private TypeMirror nodeType;
+ public NodeData(NodeData copy, String templateMethodName, String nodeId) {
+ super(copy.getTemplateType(), templateMethodName, null);
+ this.nodeId = nodeId;
+ this.declaringNode = copy.declaringNode;
+ this.declaredChildren = copy.declaredChildren;
+ this.typeSystem = copy.typeSystem;
+ this.nodeType = copy.nodeType;
+ this.specializations = copy.specializations;
+ this.specializationListeners = copy.specializationListeners;
+ this.guards = copy.guards;
+ this.executableTypes = copy.executableTypes;
+ this.shortCircuits = copy.shortCircuits;
- public NodeData(TypeElement type, TypeSystemData typeSystem) {
- super(type, null);
- this.typeSystem = typeSystem;
+ List fieldsCopy = new ArrayList<>();
+ for (NodeFieldData field : copy.fields) {
+ NodeFieldData newField = new NodeFieldData(field);
+ newField.setNode(this);
+ fieldsCopy.add(newField);
+ }
+ this.fields = fieldsCopy;
+ }
+
+ public ParameterSpec getInstanceParameterSpec() {
+ return instanceParameterSpec;
+ }
+
+ public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
+ this.instanceParameterSpec = instanceParameter;
+ }
+
+ public String getNodeId() {
+ return nodeId;
}
public TypeMirror getNodeType() {
@@ -71,6 +108,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 +132,12 @@
this.declaredChildren = declaredChildren;
for (NodeData child : declaredChildren) {
- child.parent = this;
+ child.declaringNode = this;
}
}
public NodeData getParent() {
- return parent;
+ return declaringNode;
}
public List getDeclaredChildren() {
@@ -112,17 +158,14 @@
}
}
- 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 +176,6 @@
return foundGuards;
}
- public ExecutableTypeData[] getExecutableTypes() {
- return executableTypes;
- }
-
public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) {
List types = findGenericExecutableTypes(context);
for (ExecutableTypeData availableType : types) {
@@ -180,47 +219,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);
}
}
}
@@ -249,7 +261,7 @@
}
}
- needsRewrites &= specializations.length >= 2;
+ needsRewrites &= specializations.size() >= 2;
return needsRewrites;
}
@@ -270,26 +282,15 @@
}
}
- 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)));
+ b.append(String.format("[id = %s, name = %s\n typeSystem = %s\n fields = %s\n types = %s\n specializations = %s\n guards = %s\n enclosing = %s\n enclosed = %s\n]", getNodeId(),
+ Utils.getQualifiedName(getTemplateType()), getTypeSystem(), dumpList(fields), dumpList(getExecutableTypes()), dumpList(getSpecializations()), dumpList(guards),
+ dumpList(getDeclaredChildren()), getParent()));
return b.toString();
}
- private static String dumpList(Object[] array) {
+ private static String dumpList(List> array) {
if (array == null) {
return "null";
}
@@ -315,4 +316,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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java Tue Mar 12 11:38:52 2013 +0100
@@ -28,7 +28,7 @@
public class NodeFieldData {
public enum FieldKind {
- FIELD, CHILD, CHILDREN
+ CHILD, CHILDREN
}
public enum ExecutionKind {
@@ -41,7 +41,7 @@
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) {
this.fieldElement = fieldElement;
@@ -52,10 +52,23 @@
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;
+ }
+
public boolean isShortCircuit() {
return executionKind == ExecutionKind.SHORT_CIRCUIT;
}
+ void setNode(NodeData nodeData) {
+ this.nodeData = nodeData;
+ }
+
public VariableElement getFieldElement() {
return fieldElement;
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -41,11 +41,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 +52,14 @@
@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);
+ node = resolveNode((TypeElement) element);
} finally {
- if (Log.DEBUG) {
- NodeData parsed = parsedNodes.get(Utils.getQualifiedName(originalType));
- if (parsed != null) {
- String dump = parsed.dump();
- log.error("Node parsed: %s", dump);
- System.out.println("Parsed: " + dump);
- }
- }
parsedNodes = null;
- originalType = null;
}
+ return node;
}
@Override
@@ -78,182 +67,450 @@
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);
+ NodeData rootNode = parseNode(rootType);
if (rootNode == null && children.size() > 0) {
- rootNode = new NodeData(rootType, null);
+ rootNode = new NodeData(rootType, null, rootType.getSimpleName().toString());
+ }
+
+ parsedNodes.put(typeName, rootNode);
+
+ if (rootNode != null) {
+ children.addAll(rootNode.getDeclaredChildren());
+ rootNode.setDeclaredChildren(children);
}
- if (rootNode != null) {
- rootNode.setDeclaredChildren(children);
+
+ if (Log.DEBUG) {
+ NodeData parsed = parsedNodes.get(typeName);
+ if (parsed != null) {
+ String dump = parsed.dump();
+ String valid = rootNode != null ? "" : " failed";
+ String msg = String.format("Node parsing %s : %s", valid, dump);
+ log.error(msg);
+ System.out.println(msg);
+ }
}
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
}
+ TypeElement nodeType;
+ boolean needsSplit;
+ if (methodNodes != null) {
+ needsSplit = methodNodes != null;
+ nodeType = Utils.fromTypeMirror(Utils.getAnnotationValue(TypeMirror.class, methodNodes, "value"));
+ } else {
+ needsSplit = false;
+ nodeType = type;
+ }
+
if (type.getModifiers().contains(Modifier.PRIVATE)) {
return null; // not visible
}
- 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());
+ NodeData nodeData = parseNodeData(type, nodeType);
+ if (nodeData == null) {
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);
-
+ List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(type));
nodeData.setExtensionElements(getExtensionParser().parseAll(type, elements));
if (nodeData.getExtensionElements() != null) {
elements.addAll(nodeData.getExtensionElements());
}
- List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements));
-
- nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()]));
-
- parsedNodes.put(Utils.getQualifiedName(type), nodeData);
-
- NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy);
- if (fields == null) {
+ if (!parseMethods(nodeData, elements)) {
return null;
}
- nodeData.setFields(fields);
- 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()]));
+ List nodes;
+ if (needsSplit) {
+ nodes = splitNodeData(nodeData);
+ if (nodes == null) {
+ return null;
+ }
+ } else {
+ nodes = new ArrayList<>();
+ nodes.add(nodeData);
+ }
- 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);
+ boolean valid = true;
+ for (NodeData splittedNode : nodes) {
+ if (!finalizeSpecializations(splittedNode)) {
+ valid = false;
+ }
+ if (!verifyNode(splittedNode)) {
+ valid = false;
+ }
+ }
- if (specializations == null || genericSpecializations == null || shortCircuits == null || listeners == null || guards == null) {
+ if (!valid) {
return null;
}
+ if (needsSplit) {
+ nodeData.setDeclaredChildren(nodes);
+ nodeData.setSpecializationListeners(new ArrayList());
+ nodeData.setSpecializations(new ArrayList());
+ return nodeData;
+ } else {
+ return nodeData;
+ }
+ }
+
+ 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<>();
+ }
+
+ 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;
+ }
+
+ 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 boolean 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 (generics == null || specializations == null || node.getGuards() == null || node.getShortCircuits() == null || node.getSpecializationListeners() == null) {
+ return false;
+ }
+
+ List allSpecializations = new ArrayList<>();
+ allSpecializations.addAll(generics);
+ allSpecializations.addAll(specializations);
+
+ node.setSpecializations(allSpecializations);
+
+ return true;
+ }
+
+ private boolean finalizeSpecializations(final NodeData node) {
+ List specializations = new ArrayList<>(node.getSpecializations());
+
+ if (specializations.isEmpty()) {
+ return true;
+ }
+
+ List generics = new ArrayList<>();
+ for (SpecializationData spec : specializations) {
+ if (spec.isGeneric()) {
+ generics.add(spec);
+ }
+ }
+
SpecializationData genericSpecialization = null;
- if (genericSpecializations.size() > 1) {
- for (SpecializationData generic : genericSpecializations) {
+ if (generics.size() > 1) {
+ for (SpecializationData generic : generics) {
log.error(generic.getMethod(), "Only one method with @%s is allowed per operation.", Generic.class.getSimpleName());
}
- return null;
- } else if (genericSpecializations.size() == 1) {
- genericSpecialization = genericSpecializations.get(0);
+ return false;
+ } else if (generics.size() == 1) {
+ genericSpecialization = generics.get(0);
+ } else {
+ // TODO support generation of generic if not ambiguous.
}
if (specializations.size() > 1 && genericSpecialization == null) {
- log.error(type, "Need a @%s method.", Generic.class.getSimpleName());
- return null;
+ log.error(node.getTemplateType(), "Need a @%s method.", Generic.class.getSimpleName());
+ return false;
+ }
+
+ if (genericSpecialization != null) {
+ CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized");
+ TemplateMethod uninializedMethod = new TemplateMethod(genericSpecialization.getId(), 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);
+ return true;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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();
+ }
+ }
+
+ private boolean verifyNode(NodeData nodeData) {
+ // verify specialization parameter length
+ if (!verifySpecializationParameters(nodeData)) {
+ return false;
}
// verify order is not ambiguous
- if (!verifySpecializationOrder(typeSystem, specializations)) {
+ if (!verifySpecializationOrder(nodeData)) {
+ return false;
+ }
+
+ if (!verifyMissingAbstractMethods(nodeData)) {
+ return false;
+ }
+
+ if (!assignShortCircuitsToSpecializations(nodeData)) {
+ return false;
+ }
+
+ if (!verifyConstructors(nodeData)) {
+ return false;
+ }
+
+// if (!verifyNamingConvention(specializations, "do")) {
+// return null;
+// }
+//
+// if (!verifyNamesUnique(specializations)) {
+// return null;
+// }
+
+ if (!verifyNamingConvention(nodeData.getShortCircuits(), "needs")) {
+ return false;
+ }
+
+ if (!verifySpecializationThrows(nodeData)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ 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);
+
+ AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
+ if (typeSystemMirror == null) {
+ log.error(templateType, "No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), nodeType.getQualifiedName().toString());
return null;
}
- nodeData.setSpecializations(allSpecializations.toArray(new SpecializationData[allSpecializations.size()]));
- nodeData.setSpecializationListeners(listeners.toArray(new TemplateMethod[listeners.size()]));
-
- if (!verifyMissingAbstractMethods(nodeData, elements)) {
- return null;
- }
-
- if (!assignShortCircuitsToSpecializations(nodeData, allSpecializations, shortCircuits)) {
- return null;
- }
-
- if (!verifyConstructors(nodeData)) {
+ TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
+ final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
+ if (typeSystem == null) {
+ log.error(templateType, "The used type system '%s' is invalid.", Utils.getQualifiedName(typeSytemType));
return null;
}
- if (!verifyNamingConvention(specializations, "do")) {
- return null;
- }
+ NodeData nodeData = new NodeData(templateType, typeSystem, templateType.getSimpleName().toString());
+ nodeData.setNodeType(nodeType.asType());
+
+ List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements));
- if (!verifyNamesUnique(specializations)) {
+ nodeData.setExecutableTypes(executableTypes);
+
+ parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
+
+ List fields = parseFields(nodeData, elements, typeHierarchy);
+ if (fields == null) {
return null;
}
-
- if (!verifyNamingConvention(shortCircuits, "needs")) {
- return null;
- }
-
- if (!verifySpecializationThrows(typeSystem, specializations)) {
- return null;
- }
+ nodeData.setFields(fields);
return nodeData;
}
- private boolean verifyMissingAbstractMethods(NodeData nodeData, List elements) {
+ private boolean 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()) {
+ context.getLog().error(specialization.getMethod(), specialization.getMarkerAnnotation(), "All specializations must have the same number of arguments.");
+ }
+ }
+ return valid;
+ }
+
+ private boolean verifyMissingAbstractMethods(NodeData nodeData) {
if (nodeData.needsFactory()) {
// missing abstract methods only needs to be implemented
// if we need go generate factory for it.
return true;
}
+ List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(nodeData.getTemplateType()));
+
Set unusedElements = new HashSet<>(elements);
for (TemplateMethod method : nodeData.getAllTemplateMethods()) {
unusedElements.remove(method.getMethod());
@@ -347,13 +604,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,7 +618,7 @@
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"));
}
}
@@ -394,9 +651,8 @@
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,10 +680,10 @@
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;
@@ -444,13 +700,12 @@
context.getLog().error(errorElement, "No executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
return null;
}
+
+ // 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);
}
@@ -482,8 +737,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 +760,17 @@
});
}
- private boolean assignShortCircuitsToSpecializations(NodeData nodeData, List specializations, List shortCircuits) {
-
- Map> groupedShortCircuits = groupShortCircuits(shortCircuits);
+ private boolean 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);
+ log.error(node.getTemplateType(), "@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
valid = false;
continue;
}
@@ -539,14 +793,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);
+ log.error(node.getTemplateType(), "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
valid = false;
continue;
}
@@ -562,8 +816,8 @@
return valid;
}
- NodeFieldData[] fields = nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT);
- for (SpecializationData specialization : specializations) {
+ NodeFieldData[] fields = node.filterFields(null, ExecutionKind.SHORT_CIRCUIT);
+ for (SpecializationData specialization : node.getSpecializations()) {
ShortCircuitData[] assignedShortCuts = new ShortCircuitData[fields.length];
for (int i = 0; i < fields.length; i++) {
@@ -599,6 +853,7 @@
return valid;
}
+ @SuppressWarnings("unused")
private boolean verifyNamesUnique(List extends TemplateMethod> methods) {
boolean valid = true;
for (int i = 0; i < methods.size(); i++) {
@@ -617,9 +872,9 @@
}
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 +923,10 @@
return collection;
}
- private boolean verifySpecializationOrder(TypeSystemData typeSystem, List specializations) {
+ private boolean 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++) {
@@ -696,31 +954,19 @@
return true;
}
- private boolean verifySpecializationThrows(TypeSystemData typeSystem, List specializations) {
+ private boolean 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());
+ AnnotationValue javaClassValue = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "rewriteOn");
+ log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), javaClassValue, "Duplicate exception type.");
valid = false;
}
}
@@ -744,8 +990,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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -48,14 +48,14 @@
@Override
public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
- String shortCircuitValue = Utils.getAnnotationValueString(mirror, "value");
+ String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
if (!shortCircuitValues.contains(shortCircuitValue)) {
getContext().getLog().error(method, mirror, "Invalid short circuit value %s.", shortCircuitValue);
return null;
}
- return createDefaultMethodSpec(shortCircuitValue);
+ return createDefaultMethodSpec(method, mirror, shortCircuitValue);
}
@Override
@@ -65,7 +65,7 @@
@Override
public ShortCircuitData create(TemplateMethod method) {
- String shortCircuitValue = Utils.getAnnotationValueString(method.getMarkerAnnotation(), "value");
+ String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value");
assert shortCircuitValue != null;
assert shortCircuitValues.contains(shortCircuitValue);
return new ShortCircuitData(method, shortCircuitValue);
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Tue Mar 12 11:38:52 2013 +0100
@@ -22,6 +22,8 @@
*/
package com.oracle.truffle.codegen.processor.node;
+import java.util.*;
+
import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.codegen.processor.template.*;
@@ -30,13 +32,13 @@
private final int order;
private final boolean generic;
private final boolean uninitialized;
- private final SpecializationThrowsData[] exceptions;
+ private final List exceptions;
private SpecializationGuardData[] guards;
private ShortCircuitData[] 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,7 +55,7 @@
this.order = Specialization.DEFAULT_ORDER;
this.generic = generic;
this.uninitialized = uninitialized;
- this.exceptions = new SpecializationThrowsData[0];
+ this.exceptions = Collections.emptyList();
this.guards = new SpecializationGuardData[0];
}
@@ -81,7 +83,7 @@
return uninitialized;
}
- public SpecializationThrowsData[] getExceptions() {
+ public List getExceptions() {
return exceptions;
}
@@ -106,10 +108,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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java Tue Mar 12 11:38:52 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.");
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);
+ List exceptionTypes = Utils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn");
+ List exceptionData = new ArrayList<>();
+ for (TypeMirror exceptionType : exceptionTypes) {
+ exceptionData.add(new SpecializationThrowsData(method.getMarkerAnnotation(), exceptionType));
- 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));
+ if (!Utils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) {
+ getContext().getLog().error(method.getMethod(), "Method must specify a throws clause with the exception type '%s'.", Utils.getQualifiedName(exceptionType));
return null;
}
}
- Arrays.sort(exceptionData, new Comparator() {
+ Collections.sort(exceptionData, new Comparator() {
@Override
public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) {
@@ -87,24 +81,24 @@
});
SpecializationData specialization = new SpecializationData(method, order, exceptionData);
boolean valid = true;
- List guardDefs = Utils.collectAnnotations(getContext(), method.getMarkerAnnotation(), "guards", method.getMethod(), SpecializationGuard.class);
+ List guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
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");
+ String guardMethod = guardDefs.get(i);
+
+ boolean onSpecialization = true;
+ boolean onExecution = true;
if (!onSpecialization && !onExecution) {
String message = "Either onSpecialization, onExecution or both must be enabled.";
- getContext().getLog().error(method.getMethod(), guardMirror, message);
+ getContext().getLog().error(method.getMethod(), message);
valid = false;
continue;
}
guardData[i] = new SpecializationGuardData(guardMethod, onSpecialization, onExecution);
- GuardData compatibleGuard = matchSpecializationGuard(guardMirror, specialization, guardData[i]);
+ GuardData compatibleGuard = matchSpecializationGuard(specialization, guardData[i]);
if (compatibleGuard != null) {
guardData[i].setGuardDeclaration(compatibleGuard);
} else {
@@ -121,7 +115,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,8 +136,8 @@
}
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);
+ AnnotationValue value = Utils.getAnnotationValue(specialization.getMarkerAnnotation(), "guards");
+ getContext().getLog().error(specialization.getMethod(), specialization.getMarkerAnnotation(), value, "No guard with signature '%s' found in type system.", expectedSignature);
return null;
}
@@ -151,7 +145,7 @@
}
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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java Tue Mar 12 11:38:52 2013 +0100
@@ -29,13 +29,11 @@
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, TypeMirror javaClass) {
this.annotationMirror = annotationMirror;
this.javaClass = javaClass;
- this.transitionTo = transitionTo;
}
void setSpecialization(SpecializationData specialization) {
@@ -54,16 +52,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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Tue Mar 12 11:38:52 2013 +0100
@@ -39,7 +39,8 @@
private final String name;
private final TypeMirror[] 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) {
this.allowedTypes = allowedTypes;
@@ -63,6 +64,18 @@
this(name, nodeTypeMirrors(nodeData), optional, cardinality);
}
+ public boolean isIndexed() {
+ return indexed;
+ }
+
+ public void setIndexed(boolean indexed) {
+ this.indexed = indexed;
+ }
+
+ public void setCardinality(Cardinality cardinality) {
+ this.cardinality = cardinality;
+ }
+
private static TypeMirror[] nodeTypeMirrors(NodeData nodeData) {
Set typeMirrors = new LinkedHashSet<>();
@@ -95,6 +108,7 @@
for (int i = 0; i < allowedTypes.length; i++) {
TypeMirror mirror = allowedTypes[i];
if (Utils.typeEquals(actualType, mirror)) {
+
return true;
}
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java Tue Mar 12 11:38:52 2013 +0100
@@ -32,15 +32,21 @@
public abstract class Template {
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;
}
+ public String getTemplateMethodName() {
+ return templateMethodName;
+ }
+
public TypeElement getTemplateType() {
return templateType;
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Tue Mar 12 11:38:52 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.*;
+
+import com.oracle.truffle.codegen.processor.*;
public class TemplateMethod {
+ 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,15 @@
}
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);
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
}
public Template getTemplate() {
@@ -64,28 +80,40 @@
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;
}
@@ -100,7 +128,7 @@
@Override
public String toString() {
- return getClass().getSimpleName() + " [method = " + method + "]";
+ return "id = " + getId() + ", " + getClass().getSimpleName() + " [method = " + getMethod() + "]";
}
public ActualParameter getPreviousParam(ActualParameter searchParam) {
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Tue Mar 12 11:38:52 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,7 +96,7 @@
mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
}
- if (method.getModifiers().contains(Modifier.PRIVATE)) {
+ if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) {
getContext().getLog().error(method, "Method must not be private.");
valid = false;
continue;
@@ -126,7 +127,7 @@
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()) {
String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
@@ -140,88 +141,101 @@
return null;
}
- Iterator extends VariableElement> variableIterator = method.getParameters().iterator();
+ 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()) {
+ 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));
+ context.getLog().error(method, annotation, message);
+ }
+ 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");
+ }
+
+ 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 +244,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) {
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java Tue Mar 12 11:38:52 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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java Tue Mar 12 11:38:52 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.*;
@@ -47,14 +48,14 @@
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");
+ ActualParameter parameter = method.findParameter("valueValue");
return new TypeCastData(method, parameter.getActualTypeData(getTypeSystem()), targetType);
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java Tue Mar 12 11:38:52 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.*;
@@ -47,7 +48,7 @@
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;
}
@@ -55,7 +56,7 @@
public TypeCheckData create(TemplateMethod method) {
TypeData checkedType = findTypeByMethodName(method.getMethod(), method.getMarkerAnnotation(), "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 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Tue Mar 12 11:38:52 2013 +0100
@@ -40,7 +40,7 @@
private final List typeChecks = new ArrayList<>();
public TypeData(TypeElement templateType, AnnotationMirror annotation, TypeMirror primitiveType, TypeMirror boxedType) {
- super(templateType, annotation);
+ super(templateType, null, annotation);
this.primitiveType = primitiveType;
this.boxedType = boxedType;
}
diff -r 2c5df42999dd -r edc414f52e2b 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 Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java Tue Mar 12 11:38:52 2013 +0100
@@ -41,7 +41,7 @@
private final TypeData voidType;
public TypeSystemData(TypeElement templateType, AnnotationMirror annotation, TypeData[] types, TypeMirror genericType, TypeData voidType) {
- super(templateType, annotation);
+ super(templateType, null, annotation);
this.types = types;
this.genericType = genericType;
this.voidType = voidType;
diff -r 2c5df42999dd -r edc414f52e2b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java Tue Mar 12 11:38:52 2013 +0100
@@ -145,7 +145,7 @@
}
private TypeData[] parseTypes(TypeElement templateType, AnnotationMirror templateTypeAnnotation) {
- List typeMirrors = Utils.getAnnotationValueList(templateTypeAnnotation, "value");
+ List typeMirrors = Utils.getAnnotationValueList(TypeMirror.class, templateTypeAnnotation, "value");
if (typeMirrors.size() == 0) {
log.error(templateType, templateTypeAnnotation, "At least one type must be defined.");
return null;
diff -r 2c5df42999dd -r edc414f52e2b graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java Tue Mar 12 11:38:52 2013 +0100
@@ -37,11 +37,6 @@
super(node);
}
- @Generic
- public Object doGeneric(Object left, Object right) {
- throw new RuntimeException("Arithmetic not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
- }
-
public abstract static class AddNode extends ArithmeticNode {
public AddNode(TypedNode left, TypedNode right) {
@@ -52,9 +47,8 @@
super(node);
}
- @Specialization
- @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
- int doInteger(int left, int right) {
+ @Specialization(rewriteOn = ArithmeticException.class)
+ int doInt(int left, int right) {
return ExactMath.addExact(left, right);
}
@@ -64,15 +58,19 @@
}
@Specialization
- String doStringDirect(String left, String right) {
+ String doString(String left, String right) {
return left + right;
}
- @Specialization
- @SpecializationGuard(methodName = "isString")
- String doString(Object left, Object right) {
+ @Specialization(guards = "isString")
+ String add(Object left, Object right) {
return left.toString() + right.toString();
}
+
+ @Generic
+ public Object addGeneric(Object left, Object right) {
+ throw new RuntimeException("Arithmetic not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+ }
}
public abstract static class SubNode extends ArithmeticNode {
@@ -85,16 +83,20 @@
super(node);
}
- @Specialization
- @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
- int doInteger(int left, int right) {
+ @Specialization(rewriteOn = ArithmeticException.class)
+ int sub(int left, int right) {
return ExactMath.subtractExact(left, right);
}
@Specialization
- BigInteger doBigInteger(BigInteger left, BigInteger right) {
+ BigInteger sub(BigInteger left, BigInteger right) {
return left.subtract(right);
}
+
+ @Generic
+ public Object sub(Object left, Object right) {
+ throw new RuntimeException("Arithmetic not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+ }
}
public abstract static class DivNode extends ArithmeticNode {
@@ -107,16 +109,20 @@
super(node);
}
- @Specialization
- @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
- int doInteger(int left, int right) {
+ @Specialization(rewriteOn = ArithmeticException.class)
+ int div(int left, int right) {
return left / right;
}
@Specialization
- BigInteger doBigInteger(BigInteger left, BigInteger right) {
+ BigInteger div(BigInteger left, BigInteger right) {
return left.divide(right);
}
+
+ @Generic
+ public Object div(Object left, Object right) {
+ throw new RuntimeException("Arithmetic not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+ }
}
public abstract static class MulNode extends ArithmeticNode {
@@ -129,16 +135,20 @@
super(node);
}
- @Specialization
- @SpecializationThrows(javaClass = ArithmeticException.class, transitionTo = "doBigInteger")
- int doInteger(int left, int right) {
+ @Specialization(rewriteOn = ArithmeticException.class)
+ int mul(int left, int right) {
return ExactMath.multiplyExact(left, right);
}
@Specialization
- BigInteger doBigInteger(BigInteger left, BigInteger right) {
+ BigInteger mul(BigInteger left, BigInteger right) {
return left.multiply(right);
}
+
+ @Generic
+ public Object mul(Object left, Object right) {
+ throw new RuntimeException("Arithmetic not defined for types " + left.getClass().getSimpleName() + ", " + right.getClass().getSimpleName());
+ }
}
}
diff -r 2c5df42999dd -r edc414f52e2b graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java Tue Mar 12 11:38:52 2013 +0100
@@ -46,8 +46,7 @@
return left.compareTo(right) < 0;
}
- @Specialization
- @SpecializationGuard(methodName = "isString")
+ @Specialization(guards = "isString")
public boolean doString(Object left, Object right) {
return left.toString().compareTo(right.toString()) < 0;
}
diff -r 2c5df42999dd -r edc414f52e2b graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TypedNode.java
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TypedNode.java Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TypedNode.java Tue Mar 12 11:38:52 2013 +0100
@@ -24,7 +24,6 @@
import java.math.*;
-import com.oracle.truffle.api.codegen.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.*;
@@ -49,7 +48,6 @@
public abstract Object executeGeneric(VirtualFrame frame);
- @GuardCheck
public boolean isString(Object a, Object b) {
return a instanceof String || b instanceof String;
}
diff -r 2c5df42999dd -r edc414f52e2b graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Tue Mar 12 10:02:20 2013 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Tue Mar 12 11:38:52 2013 +0100
@@ -41,31 +41,31 @@
}
@Specialization
- public int doInteger(VirtualFrame frame, int right) {
+ public int write(VirtualFrame frame, int right) {
frame.setInt(slot, right);
return right;
}
@Specialization
- public BigInteger doBigInteger(VirtualFrame frame, BigInteger right) {
+ public BigInteger write(VirtualFrame frame, BigInteger right) {
frame.setObject(slot, right);
return right;
}
@Specialization
- public boolean doBoolean(VirtualFrame frame, boolean right) {
+ public boolean write(VirtualFrame frame, boolean right) {
frame.setBoolean(slot, right);
return right;
}
@Specialization
- public String doString(VirtualFrame frame, String right) {
+ public String write(VirtualFrame frame, String right) {
frame.setObject(slot, right);
return right;
}
@Generic
- public Object doGeneric(VirtualFrame frame, Object right) {
+ public Object write(VirtualFrame frame, Object right) {
frame.setObject(slot, right);
return right;
}
diff -r 2c5df42999dd -r edc414f52e2b mx/projects
--- a/mx/projects Tue Mar 12 10:02:20 2013 +0100
+++ b/mx/projects Tue Mar 12 11:38:52 2013 +0100
@@ -366,10 +366,18 @@
# truffle.api.codegen
project@com.oracle.truffle.api.codegen@subDir=graal
project@com.oracle.truffle.api.codegen@sourceDirs=src
-project@com.oracle.truffle.api.codegen@dependencies=
+project@com.oracle.truffle.api.codegen@dependencies=com.oracle.truffle.api
project@com.oracle.truffle.api.codegen@checkstyle=com.oracle.graal.graph
project@com.oracle.truffle.api.codegen@javaCompliance=1.7
+# truffle.api.codegen.test
+project@com.oracle.truffle.api.codegen.test@subDir=graal
+project@com.oracle.truffle.api.codegen.test@sourceDirs=src
+project@com.oracle.truffle.api.codegen.test@dependencies=com.oracle.truffle.api.codegen,JUNIT,com.oracle.truffle.api.test
+project@com.oracle.truffle.api.codegen.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.api.codegen.test@javaCompliance=1.7
+project@com.oracle.truffle.api.codegen.test@annotationProcessors=com.oracle.truffle.codegen.processor
+
# truffle.codegen.processor
project@com.oracle.truffle.codegen.processor@subDir=graal
project@com.oracle.truffle.codegen.processor@sourceDirs=src