diff --git a/test/built-ins/GeneratorPrototype/return/from-state-completed.js b/test/built-ins/GeneratorPrototype/return/from-state-completed.js new file mode 100644 index 0000000000..8497c954fa --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/from-state-completed.js @@ -0,0 +1,21 @@ +// Copyright (C) 2014 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + Resuming abruptly from a generator in the 'completed' state should honor the + abrupt completion and remain in the 'completed' state. +---*/ + +function* G() {} +var iter, result; + +iter = G(); +iter.next(); + +iter.return(33); + +result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/return/from-state-executing.js b/test/built-ins/GeneratorPrototype/return/from-state-executing.js new file mode 100644 index 0000000000..be2517fcd6 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/from-state-executing.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.3.2 +description: > + A TypeError should be thrown if the generator is resumed abruptly while + running. +---*/ + +var iter; +function* g() { + iter.return(42); +} + +iter = g(); +assert.throws(TypeError, function() { + iter.next(); +}); diff --git a/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js b/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js new file mode 100644 index 0000000000..8011b82c88 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js @@ -0,0 +1,25 @@ +// Copyright (C) 2014 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + Resuming abruptly from a generator in the 'suspendedStart' state should + honor the abrupt completion and trigger a transition into the 'completed' + state. +---*/ + +function* G() { + yield 1; +} +var iter = G(); +var result; + +result = iter.return(56); + +assert.sameValue(result.value, 56); +assert.sameValue(result.done, true); + +result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/return/incorrect-context.js b/test/built-ins/GeneratorPrototype/return/incorrect-context.js new file mode 100644 index 0000000000..17328db8a2 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/incorrect-context.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `return` does not defined the [[GeneratorState]] internal slot. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws(TypeError, function() { GeneratorPrototype.return.call(1); }); +assert.throws(TypeError, function() { GeneratorPrototype.return.call({}); }); +assert.throws(TypeError, function() { GeneratorPrototype.return.call(function() {}); }); +assert.throws(TypeError, function() { GeneratorPrototype.return.call(g); }); +assert.throws(TypeError, function() { GeneratorPrototype.return.call(g.prototype); }); diff --git a/test/built-ins/GeneratorPrototype/return/property-descriptor.js b/test/built-ins/GeneratorPrototype/return/property-descriptor.js new file mode 100644 index 0000000000..3ed7e2823a --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/property-descriptor.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The GeneratorPrototype intrinsic should define a `return` property that is + non-enumerable, writable, and configurable (as per section 17). +includes: [propertyHelper.js] +es6id: 25.3.1 +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'return'); +verifyWritable(GeneratorPrototype, 'return'); +verifyConfigurable(GeneratorPrototype, 'return'); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js b/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js new file mode 100644 index 0000000000..34a494d199 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused before a `try..catch` statement, `return` should + interrupt control flow as if a `return` statement had appeared at that + location in the function body. +---*/ + +function* g() { + yield; + try { + $ERROR('This code is unreachable (within `try` block)'); + } catch (e) { + throw e; + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +iter.next(); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue(result.value, + undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js b/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js new file mode 100644 index 0000000000..2e00f03989 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused after a `try..catch` statement, `return` should + interrupt control flow as if a `return` statement had appeared at that + location in the function body. +---*/ + +var afterCatch = false; +function* g() { + try { + throw new Error(); + } catch (e) {} + afterCatch = true; + yield; + $ERROR('This code is unreachable'); +} +var iter = g(); +var result; + +result = iter.next(); + +assert.sameValue(afterCatch, true); + +result = iter.return(45); +assert.sameValue( + result.value, 45, 'Result `value` following `return`' +); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js new file mode 100644 index 0000000000..4c3648a5ee --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within the `catch` block of a `try..catch` + statement, `return` should interrupt control flow as if a `return` + statement had appeared at that location in the function body. +---*/ + +var inCatch = false; +function* g() { + try { + throw new Error(); + } catch (e) { + inCatch = true; + yield; + $ERROR('This code is unreachable (within `catch` block)'); + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +result = iter.next(); + +assert.sameValue(inCatch, true); + +result = iter.return(45); +assert.sameValue( + result.value, 45, 'Result `value` following `return`' +); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js b/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js new file mode 100644 index 0000000000..646785ee97 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within the `try` block of a `try..catch` + statement, `return` should interrupt control flow as if a `return` + statement had appeared at that location in the function body. +---*/ + +var inTry = false; +function* g() { + try { + inTry = true; + yield; + $ERROR('This code is unreachable (within `try` block)'); + } catch (e) { + throw e; + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +result = iter.next(); + +assert.sameValue(inTry, true); + +result = iter.return(44); +assert.sameValue(result.value, 44, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js b/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js new file mode 100644 index 0000000000..9da2b4a1d4 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused before a `try..finally` statement, `return` + should interrupt control flow as if a `return` statement had appeared at + that location in the function body. +---*/ + +function* g() { + yield; + try { + $ERROR('This code is unreachable (within `try` block)'); + } finally { + $ERROR('This code is unreachable (within `finally` block)'); + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +iter.next(); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js b/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js new file mode 100644 index 0000000000..253fc14ef2 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused after a `try..finally` statement, `return` + should interrupt control flow as if a `return` statement had appeared at + that location in the function body. +---*/ + +var afterFinally = false; +function* g() { + try { + } finally {} + afterFinally = true; + yield; +} +var iter = g(); +var result; + +iter.next(); + +assert.sameValue(afterFinally, true); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js new file mode 100644 index 0000000000..96baefa616 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js @@ -0,0 +1,48 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `catch` block that is declared within a + `try` block of a `try..catch` statement, `return` should interrupt control + flow as if a `return` statement had appeared at that location in the + function body. +---*/ + +var inCatch = false; +var inFinally = false; +function* g() { + try { + try { + throw new Error(); + } catch (e) { + inCatch = true; + yield; + $ERROR('This code is unreachable (within `catch` block)'); + } + $ERROR('This code is unreachable (following nested `try` statement)'); + } finally { + inFinally = true; + } + $ERROR('This code is unreachable (following outer `try` statement)'); +} +var iter = g(); +var result; + +result = iter.next(); + +assert.sameValue(inCatch, true, '`catch` code patch executed'); +assert.sameValue(inFinally, false, '`finally` code path not executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when compelete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js new file mode 100644 index 0000000000..b145c8b70a --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `finally` block of a `try..catch` + statement, `return` should interrupt control flow as if a `return` + statement had appeared at that location in the function body. +---*/ + +var inFinally = false; +function* g() { + try { + throw new Error(); + try { + } catch (e) {} + } finally { + inFinally = true; + yield; + $ERROR('This code is unreachable (within `finally` block)'); + } + $ERROR('This code is unreachable (following outer `try` statement)'); +} +var iter = g(); +var result; + +result = iter.next(); + +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js new file mode 100644 index 0000000000..99a3e5ab37 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js @@ -0,0 +1,50 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `try` block that is declared within a + `try` block of a `try..catch` statement, `return` should interrupt control + flow as if a `return` statement had appeared at that location in the + function body. +---*/ + +var inTry = false; +var inFinally = false; +function* g() { + try { + try { + inTry = true; + yield; + $ERROR('This code is unreachable (within nested `try` block)'); + } catch (e) { + throw e; + } + $ERROR('This code is unreachable (following nested `try` statement)'); + } finally { + inFinally = true; + } + $ERROR('This code is unreachable (following outer `try` statement)'); +} +var iter = g(); +var exception = new Error(); +var result; + +iter.next(); + +assert.sameValue(inTry, true, 'Nested `try` code patch executed'); +assert.sameValue(inFinally, false, '`finally` code path not executed'); + +result = iter.return(45); + +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js new file mode 100644 index 0000000000..15d4fa1f24 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `try` block of a `try..catch` statement + and following a nested `try..catch` statment, `return` should interrupt + control flow as if a `return` statement had appeared at that location in + the function body. +---*/ + +var inCatch = false; +var inFinally = false; +function* g() { + try { + try { + throw new Error(); + } catch (e) { + inCatch = true; + } + } finally { + inFinally = true; + } + yield; + $ERROR('This code is unreachable'); +} +var iter = g(); +var result; + + iter.next(); + +assert.sameValue(inCatch, true, '`catch` code path executed'); +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js new file mode 100644 index 0000000000..5e4b87999c --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js @@ -0,0 +1,48 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `try` block of a `try..catch` statement + and before a nested `try..catch` statement, `return` should interrupt + control flow as if a `return` statement had appeared at that location in + the function body. +---*/ + +var inTry = false; +var inFinally = false; +function* g() { + try { + inTry = true; + yield; + try { + $ERROR('This code is unreachable (within nested `try` block)'); + } catch (e) { + throw e; + } + $ERROR('This code is unreacahable (following nested `try` statement)'); + } finally { + inFinally = true; + } + $ERROR('This codeis unreachable (following outer `try` statement)'); +} +var iter = g(); +var result; + +iter.next(); + +assert.sameValue(inTry, true, '`try` code path executed'); +assert.sameValue(inFinally, false, '`finally` code path not executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js b/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js new file mode 100644 index 0000000000..ae0b022c58 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within the `finally` block of a `try..finally` + statement, `return` should interrupt control flow as if a `return` + statement had appeared at that location in the function body. +---*/ + +var inFinally = true; +function* g() { + try { + } finally { + inFinally = true; + yield; + $ERROR('This code is unreachable (within `finally` block)'); + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +iter.next(); + +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js b/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js new file mode 100644 index 0000000000..6a098be79d --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js @@ -0,0 +1,42 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.3 +description: > + When a generator is paused within a `try` block of a `try..finally` + statement, `return` should interrupt control flow as if a `return` + statement had appeared at that location in the function body. +---*/ + +var inTry = false; +var inFinally = false; +function* g() { + try { + inTry = true; + yield; + $ERROR('This code is unreachable (within `try` block)'); + } finally { + inFinally = true; + } + $ERROR('This code is unreachable (following `try` statement)'); +} +var iter = g(); +var result; + +iter.next(); + +assert.sameValue(inTry, true, '`try` block code path executed'); +assert.sameValue(inFinally, false, '`finally` code path not executed'); + +result = iter.return(45); +assert.sameValue(result.value, 45, 'Result `value` following `return`'); +assert.sameValue(result.done, true, 'Result `done` flag following `return`'); +assert.sameValue(inFinally, true, '`finally` code path executed'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js b/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js index a548fcc807..5da206774c 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js @@ -19,9 +19,8 @@ function* g() { } yield 3; } -var iter, result, exception; +var iter, result; -exception = new Test262Error(); iter = g(); result = iter.next(); assert.sameValue(result.value, 1, 'First result `value`');