diff graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java @ 13821:b16ec83edc73

Documentation and more refactoring of Simple Language
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 29 Jan 2014 20:45:43 -0800
parents 7c418666c6c9
children 64c77f0577bb
line wrap: on
line diff
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Wed Jan 29 20:43:28 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Wed Jan 29 20:45:43 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,29 +22,37 @@
  */
 package com.oracle.truffle.sl.nodes.controlflow;
 
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.sl.nodes.*;
 
+@NodeInfo(shortName = "while")
 public class SLWhileNode extends SLStatementNode {
 
-    @Child private SLExpressionNode condition;
-    @Child private SLStatementNode body;
+    @Child private SLExpressionNode conditionNode;
+    @Child private SLStatementNode bodyNode;
 
     private final BranchProfile continueTaken = new BranchProfile();
     private final BranchProfile breakTaken = new BranchProfile();
 
-    public SLWhileNode(SLExpressionNode condition, SLStatementNode body) {
-        this.condition = adoptChild(condition);
-        this.body = adoptChild(body);
+    public SLWhileNode(SLExpressionNode conditionNode, SLStatementNode bodyNode) {
+        this.conditionNode = adoptChild(conditionNode);
+        this.bodyNode = adoptChild(bodyNode);
     }
 
     @Override
     public void executeVoid(VirtualFrame frame) {
+        int count = 0;
         try {
-            while (condition.executeCondition(frame)) {
+            while (evaluateCondition(frame)) {
                 try {
-                    body.executeVoid(frame);
+                    bodyNode.executeVoid(frame);
+                    if (CompilerDirectives.inInterpreter()) {
+                        count++;
+                    }
                 } catch (SLContinueException ex) {
                     continueTaken.enter();
                     /* Fall through to next loop iteration. */
@@ -53,6 +61,34 @@
         } catch (SLBreakException ex) {
             breakTaken.enter();
             /* Done executing this loop, exit method to execute statement following the loop. */
+        } finally {
+            if (CompilerDirectives.inInterpreter()) {
+                /*
+                 * Report the loop count to the Truffle system. It is used for compilation and
+                 * inlining decisions.
+                 */
+                RootNode root = getRootNode();
+                if (root.getCallTarget() instanceof LoopCountReceiver) {
+                    ((LoopCountReceiver) root.getCallTarget()).reportLoopCount(count);
+                }
+            }
+        }
+    }
+
+    private boolean evaluateCondition(VirtualFrame frame) {
+        try {
+            /*
+             * The condition must evaluate to a boolean value, so we call boolean-specialized
+             * method.
+             */
+            return conditionNode.executeBoolean(frame);
+        } catch (UnexpectedResultException ex) {
+            /*
+             * The condition evaluated to a non-boolean result. This is a type error in the SL
+             * program. We report it with the same exception that Truffle DSL generated nodes use to
+             * report type errors.
+             */
+            throw new UnsupportedSpecializationException(this, ex.getResult());
         }
     }
 }