Mercurial > hg > truffle
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()); } } }