Mercurial > hg > truffle
comparison graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java @ 16917:6af9d523222a
SL: use new LoopNode API.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Sat, 23 Aug 2014 19:31:44 +0200 |
parents | abe7128ca473 |
children |
comparison
equal
deleted
inserted
replaced
16916:534a87f866dc | 16917:6af9d523222a |
---|---|
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package com.oracle.truffle.sl.nodes.controlflow; | 23 package com.oracle.truffle.sl.nodes.controlflow; |
24 | 24 |
25 import com.oracle.truffle.api.*; | 25 import com.oracle.truffle.api.*; |
26 import com.oracle.truffle.api.dsl.*; | |
27 import com.oracle.truffle.api.frame.*; | 26 import com.oracle.truffle.api.frame.*; |
28 import com.oracle.truffle.api.nodes.*; | 27 import com.oracle.truffle.api.nodes.*; |
29 import com.oracle.truffle.api.source.*; | 28 import com.oracle.truffle.api.source.*; |
30 import com.oracle.truffle.api.utilities.*; | |
31 import com.oracle.truffle.sl.nodes.*; | 29 import com.oracle.truffle.sl.nodes.*; |
32 | 30 |
33 @NodeInfo(shortName = "while", description = "The node implementing a while loop") | 31 @NodeInfo(shortName = "while", description = "The node implementing a while loop") |
34 public final class SLWhileNode extends SLStatementNode { | 32 public final class SLWhileNode extends SLStatementNode { |
35 | 33 |
36 /** | 34 @Child private LoopNode loopNode; |
37 * The condition of the loop. This in a {@link SLExpressionNode} because we require a result | |
38 * value. We do not have a node type that can only return a {@code boolean} value, so | |
39 * {@link #evaluateCondition executing the condition} can lead to a type error. | |
40 */ | |
41 @Child private SLExpressionNode conditionNode; | |
42 | |
43 /** Statement (or {@link SLBlockNode block}) executed as long as the condition is true. */ | |
44 @Child private SLStatementNode bodyNode; | |
45 | |
46 /** | |
47 * Profiling information, collected by the interpreter, capturing whether a {@code continue} | |
48 * statement was used in this loop. This allows the compiler to generate better code for loops | |
49 * without a {@code continue}. | |
50 */ | |
51 private final BranchProfile continueTaken = new BranchProfile(); | |
52 private final BranchProfile breakTaken = new BranchProfile(); | |
53 | 35 |
54 public SLWhileNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode bodyNode) { | 36 public SLWhileNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode bodyNode) { |
55 super(src); | 37 super(src); |
56 this.conditionNode = conditionNode; | 38 this.loopNode = Truffle.getRuntime().createLoopNode(new SLRepeatingNode(src, conditionNode, bodyNode)); |
57 this.bodyNode = bodyNode; | |
58 } | 39 } |
59 | 40 |
60 @Override | 41 @Override |
61 public void executeVoid(VirtualFrame frame) { | 42 public void executeVoid(VirtualFrame frame) { |
62 int count = 0; | 43 loopNode.executeLoop(frame); |
63 try { | |
64 while (evaluateCondition(frame)) { | |
65 try { | |
66 /* Execute the loop body. */ | |
67 bodyNode.executeVoid(frame); | |
68 | |
69 if (CompilerDirectives.inInterpreter()) { | |
70 /* In the interpreter, profile the the number of loop iteration. */ | |
71 count++; | |
72 } | |
73 } catch (SLContinueException ex) { | |
74 /* In the interpreter, record profiling information that the loop uses continue. */ | |
75 continueTaken.enter(); | |
76 /* Fall through to next loop iteration. */ | |
77 } | |
78 } | |
79 } catch (SLBreakException ex) { | |
80 /* In the interpreter, record profiling information that the loop uses break. */ | |
81 breakTaken.enter(); | |
82 /* Done executing this loop, exit method to execute statement following the loop. */ | |
83 | |
84 } finally { | |
85 if (CompilerDirectives.inInterpreter()) { | |
86 /* | |
87 * In the interpreter, report the loop count to the Truffle system. It is used for | |
88 * compilation and inlining decisions. | |
89 */ | |
90 getRootNode().reportLoopCount(count); | |
91 } | |
92 } | |
93 } | 44 } |
94 | 45 |
95 private boolean evaluateCondition(VirtualFrame frame) { | |
96 try { | |
97 /* | |
98 * The condition must evaluate to a boolean value, so we call the boolean-specialized | |
99 * execute method. | |
100 */ | |
101 return conditionNode.executeBoolean(frame); | |
102 } catch (UnexpectedResultException ex) { | |
103 /* | |
104 * The condition evaluated to a non-boolean result. This is a type error in the SL | |
105 * program. We report it with the same exception that Truffle DSL generated nodes use to | |
106 * report type errors. | |
107 */ | |
108 throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult()); | |
109 } | |
110 } | |
111 } | 46 } |