From 24424352f455f467df097d717a1bdaf202242316 Mon Sep 17 00:00:00 2001 From: Adam Welc <adam.welc@oracle.com> Date: Mon, 13 Apr 2015 10:41:35 -0700 Subject: [PATCH] Break and next exceptions must be able to reach an outer loop. --- .../src/com/oracle/truffle/r/engine/REngine.java | 11 +++++++++-- .../com/oracle/truffle/r/test/ExpectedTestOutput.test | 3 +++ .../truffle/r/test/library/base/TestSimpleLoop.java | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 4d997ccb0b..d4d9a7bb07 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -239,7 +239,11 @@ public final class REngine implements RContext.Engine { } try { RootCallTarget callTarget = doMakeCallTarget(node, "<repl wrapper>"); - return runCall(callTarget, frame, printResult, true); + try { + return runCall(callTarget, frame, printResult, true); + } catch (BreakException | NextException cfe) { + throw RError.error(RError.Message.NO_LOOP_FOR_BREAK_NEXT); + } } catch (RError e) { // RError prints the correct result on the console return null; @@ -419,7 +423,8 @@ public final class REngine implements RContext.Engine { // condition handling can cause a "return" that needs to skip over this call throw ex; } catch (BreakException | NextException cfe) { - throw RError.error(RError.Message.NO_LOOP_FOR_BREAK_NEXT); + // there can be an outer loop + throw cfe; } assert checkResult(result); if (printResult) { @@ -432,6 +437,8 @@ public final class REngine implements RContext.Engine { throw e; } catch (ReturnException ex) { throw ex; + } catch (BreakException | NextException cfe) { + throw cfe; } catch (UnsupportedSpecializationException use) { throw use; } catch (DebugExitException | BrowserQuitException e) { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index f27d2c6156..9c0076a173 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -21290,6 +21290,9 @@ list() #{ i <- 0L ; while(i < 3L) { i <- i + 1 ; if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x } [1] 2 +##com.oracle.truffle.r.test.library.base.TestSimpleLoop.testLoopsBreakNext +#{ x <- repeat tryCatch({break}, handler = function(e) NULL) } + ##com.oracle.truffle.r.test.library.base.TestSimpleLoop.testLoopsErrors #{ break; } Error: no loop for break/next, jumping to top level diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java index 48d7e7640b..2b5666b8d6 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java @@ -70,6 +70,7 @@ public class TestSimpleLoop extends TestBase { assertEval("{ for(i in 1:4) { if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x }"); assertEval("{ i <- 0L ; while(i < 3L) { i <- i + 1 ; if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x }"); assertEval("{ f <- function(s) { for(i in s) { if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x } ; f(2:1) ; f(c(1,2,3,4)) }"); + assertEval("{ x <- repeat tryCatch({break}, handler = function(e) NULL) }"); } @Test -- GitLab