changeset 11190:4eb23800c907

Truffle-DSL: Implemented support for negated guards (GRAAL-371 #resolve)
author Christian Humer <christian.humer@gmail.com>
date Wed, 31 Jul 2013 15:36:01 +0200
parents 8ce168d68d49
children c7d9ff67beed
files graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java
diffstat 4 files changed, 79 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NegatedGuardsTest.java	Wed Jul 31 15:36:01 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.NegatedGuardsTestFactory.NegatedGuardNodeFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+public class NegatedGuardsTest {
+
+    @Test
+    public void testGuardGlobal() {
+        TestRootNode<NegatedGuardNode> root = createRoot(NegatedGuardNodeFactory.getInstance());
+        Assert.assertEquals(42, executeWith(root));
+    }
+
+    abstract static class NegatedGuardNode extends ValueNode {
+
+        static boolean guard() {
+            return true;
+        }
+
+        @Specialization(order = 1, guards = "!guard")
+        int do1() {
+            throw new AssertionError();
+        }
+
+        @Specialization(order = 2)
+        int do2() {
+            return 42; // the generic answer to all questions
+        }
+    }
+}
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Wed Jul 31 15:07:42 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Wed Jul 31 15:36:01 2013 +0200
@@ -407,6 +407,9 @@
             // Explicitly specified guards
             for (GuardData guard : guardedSpecialization.getGuards()) {
                 builder.string(andOperator);
+                if (guard.isNegated()) {
+                    builder.string("!");
+                }
                 builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null));
                 andOperator = " && ";
             }
@@ -2388,7 +2391,7 @@
             if (specialization.findNextSpecialization() != null) {
                 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
                 returnBuilder.tree(createDeoptimize(builder));
-                returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuards() + " failed"));
+                returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuardDefinitions() + " failed"));
                 returnSpecialized = returnBuilder.getRoot();
             }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java	Wed Jul 31 15:07:42 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java	Wed Jul 31 15:36:01 2013 +0200
@@ -28,12 +28,18 @@
 public class GuardData extends TemplateMethod {
 
     private final SpecializationData specialization;
+    private final boolean negated;
 
-    public GuardData(TemplateMethod method, SpecializationData specialization) {
+    public GuardData(TemplateMethod method, SpecializationData specialization, boolean negated) {
         super(method);
+        this.negated = negated;
         this.specialization = specialization;
     }
 
+    public boolean isNegated() {
+        return negated;
+    }
+
     public SpecializationData getSpecialization() {
         return specialization;
     }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java	Wed Jul 31 15:07:42 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java	Wed Jul 31 15:36:01 2013 +0200
@@ -35,11 +35,18 @@
 
     private final SpecializationData specialization;
     private final String guardName;
+    private final boolean negated;
 
-    public GuardParser(ProcessorContext context, SpecializationData specialization, String guardName) {
+    public GuardParser(ProcessorContext context, SpecializationData specialization, String guardDefinition) {
         super(context, specialization.getNode());
         this.specialization = specialization;
-        this.guardName = guardName;
+        if (guardDefinition.startsWith("!")) {
+            this.guardName = guardDefinition.substring(1, guardDefinition.length());
+            this.negated = true;
+        } else {
+            this.guardName = guardDefinition;
+            this.negated = false;
+        }
         setEmitErrors(false);
         setParseNullOnError(false);
     }
@@ -71,7 +78,7 @@
 
     @Override
     public GuardData create(TemplateMethod method) {
-        GuardData guard = new GuardData(method, specialization);
+        GuardData guard = new GuardData(method, specialization, negated);
         /*
          * Update parameters in way that parameter specifications match again the node field names
          * etc.