diff --git a/test/built-ins/GeneratorFunction/extensibility.js b/test/built-ins/GeneratorFunction/extensibility.js new file mode 100644 index 0000000000000000000000000000000000000000..e8cd2ff078cc9921390ade1224c0e0bca62d6b27 --- /dev/null +++ b/test/built-ins/GeneratorFunction/extensibility.js @@ -0,0 +1,14 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-properties-of-the-generatorfunction-constructor +es6id: 25.2.2 +description: Object extensibility +info: > + The value of the [[Extensible]] internal slot of the GeneratorFunction + constructor is true. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert(Object.isExtensible(GeneratorFunction)); diff --git a/test/built-ins/GeneratorFunction/instance-length.js b/test/built-ins/GeneratorFunction/instance-length.js new file mode 100644 index 0000000000000000000000000000000000000000..3906167d6748eb3f165a952f298f3de7e07fc22a --- /dev/null +++ b/test/built-ins/GeneratorFunction/instance-length.js @@ -0,0 +1,38 @@ +// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generatorfunction +es6id: 25.2.1.1 +description: Definition of instance `length` property +info: | + [...] + 3. Return CreateDynamicFunction(C, NewTarget, "generator", args). + + 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction + + [...] + 26. Perform FunctionInitialize(F, Normal, parameters, body, scope). + [...] + + 9.2.4 FunctionInitialize + + [...] + 3. Perform ! DefinePropertyOrThrow(F, "length", + PropertyDescriptor{[[Value]]: len, [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true}). + [...] +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert.sameValue(GeneratorFunction().length, 0); +assert.sameValue(GeneratorFunction('').length, 0); +assert.sameValue(GeneratorFunction('x').length, 0); +assert.sameValue(GeneratorFunction('x', '').length, 1); +assert.sameValue(GeneratorFunction('x', 'y', '').length, 2); +assert.sameValue(GeneratorFunction('x, y', '').length, 2); + +verifyNotEnumerable(GeneratorFunction(), 'length'); +verifyNotWritable(GeneratorFunction(), 'length'); +verifyConfigurable(GeneratorFunction(), 'length'); diff --git a/test/built-ins/GeneratorFunction/instance-prototype.js b/test/built-ins/GeneratorFunction/instance-prototype.js new file mode 100644 index 0000000000000000000000000000000000000000..dba638945a8e1bf04a4bc86ebf5651120f08fc37 --- /dev/null +++ b/test/built-ins/GeneratorFunction/instance-prototype.js @@ -0,0 +1,35 @@ +// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generatorfunction +es6id: 25.2.1.1 +description: Definition of instance `prototype` property +info: | + [...] + 3. Return CreateDynamicFunction(C, NewTarget, "generator", args). + + 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction + + [...] + 27. If kind is "generator", then + a. Let prototype be ObjectCreate(%GeneratorPrototype%). + b. Perform DefinePropertyOrThrow(F, "prototype", + PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, + [[Enumerable]]: false, [[Configurable]]: false}). + [...] +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +var instance = GeneratorFunction(); + +assert.sameValue(typeof instance.prototype, 'object'); +assert.sameValue( + Object.getPrototypeOf(instance.prototype), + Object.getPrototypeOf(instance).prototype +); + +verifyNotEnumerable(instance, 'prototype'); +verifyWritable(instance, 'prototype'); +verifyNotConfigurable(instance, 'prototype'); diff --git a/test/built-ins/GeneratorFunction/instance-yield-expr-in-param.js b/test/built-ins/GeneratorFunction/instance-yield-expr-in-param.js new file mode 100644 index 0000000000000000000000000000000000000000..e170f3c308eb6d1050ea57534d54951e07db6b4b --- /dev/null +++ b/test/built-ins/GeneratorFunction/instance-yield-expr-in-param.js @@ -0,0 +1,34 @@ +// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generatorfunction +es6id: 25.2.1.1 +description: Definition of instance `length` property +info: | + [...] + 3. Return CreateDynamicFunction(C, NewTarget, "generator", args). + + 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction + + [...] + 20. If kind is "generator", then + a. If parameters Contains YieldExpression is true, throw a SyntaxError + exception. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +// YieldExpression is permitted in function body. +GeneratorFunction('x = yield'); + +assert.throws(SyntaxError, function() { + GeneratorFunction('x = yield', ''); +}, 'YieldExpression not permitted generally'); + +var withinGenerator = function*() { + GeneratorFunction('x = yield', ''); +}; + +assert.throws(SyntaxError, function() { + withinGenerator().next(); +}, 'YieldExpression not permitted when calling context is a generator'); diff --git a/test/built-ins/GeneratorFunction/length.js b/test/built-ins/GeneratorFunction/length.js new file mode 100644 index 0000000000000000000000000000000000000000..f60239cc2aa3b59b589726df6780db1fb5645d06 --- /dev/null +++ b/test/built-ins/GeneratorFunction/length.js @@ -0,0 +1,18 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generatorfunction.length +es6id: 25.2.2.1 +description: > + This is a data property with a value of 1. This property has the attributes { + [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert.sameValue(GeneratorFunction.length, 1); + +verifyNotEnumerable(GeneratorFunction, 'length'); +verifyNotWritable(GeneratorFunction, 'length'); +verifyConfigurable(GeneratorFunction, 'length'); diff --git a/test/built-ins/GeneratorFunction/name.js b/test/built-ins/GeneratorFunction/name.js new file mode 100644 index 0000000000000000000000000000000000000000..707489cc7060cd913b298e969742d8bc067e8f41 --- /dev/null +++ b/test/built-ins/GeneratorFunction/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-properties-of-the-generatorfunction-constructor +es6id: 25.2.2 +description: Function "name" property +info: > + The value of the name property of the GeneratorFunction is + "GeneratorFunction". + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. + + Unless otherwise specified, the name property of a built-in Function object, + if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert.sameValue(GeneratorFunction.name, 'GeneratorFunction'); + +verifyNotEnumerable(GeneratorFunction, 'name'); +verifyNotWritable(GeneratorFunction, 'name'); +verifyConfigurable(GeneratorFunction, 'name'); diff --git a/test/built-ins/GeneratorFunction/prototype/constructor.js b/test/built-ins/GeneratorFunction/prototype/constructor.js new file mode 100644 index 0000000000000000000000000000000000000000..132bde1001dbcee8d7ab723f32a364d667fc9d91 --- /dev/null +++ b/test/built-ins/GeneratorFunction/prototype/constructor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generatorfunction.prototype.constructor +es6id: 25.2.3.1 +description: > + `constructor` property of the GeneratorFunction.prototype object +info: > + The initial value of GeneratorFunction.prototype.constructor is the intrinsic + object %GeneratorFunction%. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert.sameValue(GeneratorFunction.prototype.constructor, GeneratorFunction); + +verifyNotEnumerable(GeneratorFunction.prototype, 'constructor'); +verifyNotWritable(GeneratorFunction.prototype, 'constructor'); +verifyConfigurable(GeneratorFunction.prototype, 'constructor'); diff --git a/test/built-ins/GeneratorFunction/prototype/extensibility.js b/test/built-ins/GeneratorFunction/prototype/extensibility.js new file mode 100644 index 0000000000000000000000000000000000000000..231a23b0a17e2a93af7f0b32b6433c455eec6066 --- /dev/null +++ b/test/built-ins/GeneratorFunction/prototype/extensibility.js @@ -0,0 +1,14 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-properties-of-the-generatorfunction-prototype-object +es6id: 25.2.3 +description: Object extensibility +info: > + The initial value of the [[Extensible]] internal slot of the + GeneratorFunction prototype object is true. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +assert(Object.isExtensible(GeneratorFunction.prototype)); diff --git a/test/built-ins/GeneratorFunction/prototype/prop-desc.js b/test/built-ins/GeneratorFunction/prototype/prop-desc.js new file mode 100644 index 0000000000000000000000000000000000000000..ffb674591e2e3db503433d3282b0460a6afe64a7 --- /dev/null +++ b/test/built-ins/GeneratorFunction/prototype/prop-desc.js @@ -0,0 +1,16 @@ +// 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.4.5.1 +description: GeneratorFunction.prototype property descriptor +info: > + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +verifyNotEnumerable(GeneratorFunction, 'prototype'); +verifyNotWritable(GeneratorFunction, 'prototype'); +verifyNotConfigurable(GeneratorFunction, 'prototype'); diff --git a/test/built-ins/GeneratorFunction/prototype/prototype.js b/test/built-ins/GeneratorFunction/prototype/prototype.js index 742611edfc4caf06d2f5cf617313ae72d7900756..c90d452741bb5e5680ca79bee84a7a9d9be48db1 100644 --- a/test/built-ins/GeneratorFunction/prototype/prototype.js +++ b/test/built-ins/GeneratorFunction/prototype/prototype.js @@ -5,9 +5,18 @@ es6id: 25.2.3.2 description: > The value of GeneratorFunction.prototype.prototype is the %GeneratorPrototype% intrinsic object. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] ---*/ +var GeneratorFunctionPrototype = Object.getPrototypeOf(function*() {}); assert.sameValue( - Object.getPrototypeOf(function*() {}).prototype, + GeneratorFunctionPrototype.prototype, Object.getPrototypeOf(function*() {}.prototype) ); + +verifyNotEnumerable(GeneratorFunctionPrototype, 'prototype'); +verifyNotWritable(GeneratorFunctionPrototype, 'prototype'); +verifyConfigurable(GeneratorFunctionPrototype, 'prototype'); diff --git a/test/built-ins/GeneratorPrototype/next/from-state-executing.js b/test/built-ins/GeneratorPrototype/next/from-state-executing.js index 2a49244f3be06a73a5dfbf61a1c0656cf6d685a9..0490ed31dc7d121a09cf81cd0123c10fde2ff9a3 100644 --- a/test/built-ins/GeneratorPrototype/next/from-state-executing.js +++ b/test/built-ins/GeneratorPrototype/next/from-state-executing.js @@ -1,12 +1,41 @@ // Copyright (C) 2013 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: sec-generatorvalidate es6id: 25.3.3.2 description: > - A TypeError should be thrown if the generator is resumed while running. + A TypeError should be thrown if the generator is resumed while in the + "executing" state and the generator should be marked as "completed" +info: | + 25.3.3.1 GeneratorStart + + [...] + 4. Set the code evaluation state of genContext such that when evaluation is + resumed for that execution context the following steps will be performed: + a. Let result be the result of evaluating generatorBody. + b. Assert: If we return here, the generator either threw an exception or + performed either an implicit or explicit return. + c. Remove genContext from the execution context stack and restore the + execution context that is at the top of the execution context stack as + the running execution context. + d. Set generator.[[GeneratorState]] to "completed". + [...] + + 25.3.3.3 GeneratorResume + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. + 3. Assert: generator also has a [[GeneratorContext]] internal slot. + 4. Let state be generator.[[GeneratorState]]. + 5. If state is "executing", throw a TypeError exception. ---*/ -var iter; +var iter, result; function* withoutVal() { iter.next(); } @@ -17,9 +46,33 @@ function* withVal() { iter = withoutVal(); assert.throws(TypeError, function() { iter.next(); -}); +}, 'Error when invoked without value'); + +result = iter.next(); + +assert.sameValue( + typeof result, 'object', 'type following invocation without value' +); +assert.sameValue( + result.value, undefined, '`value` following invocation without value' +); +assert.sameValue( + result.done, true, '`done` following invocation without value' +); iter = withVal(); assert.throws(TypeError, function() { iter.next(); -}); +}, 'Error when invoked with value'); + +result = iter.next(); + +assert.sameValue( + typeof result, 'object', 'type following invocation with value' +); +assert.sameValue( + result.value, undefined, '`value` following invocation with value' +); +assert.sameValue( + result.done, true, '`done` following invocation with value' +); diff --git a/test/built-ins/GeneratorPrototype/next/incorrect-context.js b/test/built-ins/GeneratorPrototype/next/incorrect-context.js deleted file mode 100644 index e88f109dd506cf9cc1b4806ed97552e82fd8576a..0000000000000000000000000000000000000000 --- a/test/built-ins/GeneratorPrototype/next/incorrect-context.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2013 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -es6id: 25.3.1.2 -description: > - A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the - context of `next` does not defined the [[GeneratorState]] internal slot. ----*/ - -function* g() {} -var GeneratorPrototype = Object.getPrototypeOf(g).prototype; - -assert.throws(TypeError, function() { GeneratorPrototype.next.call(1); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(1, 1); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call({}); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call({}, 1); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}, 1); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(g); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(g, 1); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype); }); -assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype, 1); }); diff --git a/test/built-ins/GeneratorPrototype/next/this-val-not-generator.js b/test/built-ins/GeneratorPrototype/next/this-val-not-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..afabed53b259887ba940a9312c1adfdf2858424c --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/this-val-not-generator.js @@ -0,0 +1,69 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.next +es6id: 25.3.1.2 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `next` does not define the [[GeneratorState]] internal slot. +info: | + 1. Let g be the this value. + 2. Return GeneratorResume(g, value). + + 25.3.3.3 GeneratorResume + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + [...] + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call({}); }, + 'ordinary object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call({}, 1); }, + 'ordinary object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(function() {}); }, + 'function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(function() {}, 1); }, + 'function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(g); }, + 'generator function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(g, 1); }, + 'generator function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(g.prototype); }, + 'generator function prototype object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(g.prototype, 1); }, + 'generator function prototype object (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/next/this-val-not-object.js b/test/built-ins/GeneratorPrototype/next/this-val-not-object.js new file mode 100644 index 0000000000000000000000000000000000000000..6530075e6a0f29bc820108e37730929b71ef7da1 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/this-val-not-object.js @@ -0,0 +1,91 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.next +es6id: 25.3.1.2 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this" + value of `next` is not an object. +info: | + 1. Let g be the this value. + 2. Return GeneratorResume(g, value). + + 25.3.3.3 GeneratorResume + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. +features: [Symbol] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; +var symbol = Symbol(); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(undefined); }, + 'undefined (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(undefined, 1); }, + 'undefined (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(null); }, + 'null (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(null, 1); }, + 'null (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(true); }, + 'boolean (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(true, 1); }, + 'boolean (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call('s'); }, + 'string (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call('s', 1); }, + 'string (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(1); }, + 'number (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(1, 1); }, + 'number (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(symbol); }, + 'symbol (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.next.call(symbol, 1); }, + 'symbol (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/return/from-state-completed.js b/test/built-ins/GeneratorPrototype/return/from-state-completed.js index 8497c954fa944161ce717300092834e70c23f3aa..6748f90e3ca17ba01374a713fafe2f01cb036bf1 100644 --- a/test/built-ins/GeneratorPrototype/return/from-state-completed.js +++ b/test/built-ins/GeneratorPrototype/return/from-state-completed.js @@ -13,9 +13,12 @@ var iter, result; iter = G(); iter.next(); -iter.return(33); +result = iter.return(33); + +assert.sameValue(result.value, 33, 'return: result `value`'); +assert.sameValue(result.done, true, 'return: result `done` flag'); result = iter.next(); -assert.sameValue(result.value, undefined, 'Result `value`'); -assert.sameValue(result.done, true, 'Result `done` flag'); +assert.sameValue(result.value, undefined, 'next: result `value`'); +assert.sameValue(result.done, true, 'next: 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 index be2517fcd6059931fec95d89e4edb5d24571e6c6..2dc4c51536e0b2f79fff19d841c2535f8033cfa9 100644 --- a/test/built-ins/GeneratorPrototype/return/from-state-executing.js +++ b/test/built-ins/GeneratorPrototype/return/from-state-executing.js @@ -1,13 +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. /*--- +esid: sec-generatorvalidate es6id: 25.3.3.2 description: > - A TypeError should be thrown if the generator is resumed abruptly while - running. + A TypeError should be thrown if the generator is in the "executing" state, + and the generator should be marked as "completed" +info: | + 25.3.3.1 GeneratorStart + + [...] + 4. Set the code evaluation state of genContext such that when evaluation is + resumed for that execution context the following steps will be performed: + a. Let result be the result of evaluating generatorBody. + b. Assert: If we return here, the generator either threw an exception or + performed either an implicit or explicit return. + c. Remove genContext from the execution context stack and restore the + execution context that is at the top of the execution context stack as + the running execution context. + d. Set generator.[[GeneratorState]] to "completed". + [...] + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. + 3. Assert: generator also has a [[GeneratorContext]] internal slot. + 4. Let state be generator.[[GeneratorState]]. + 5. If state is "executing", throw a TypeError exception. ---*/ -var iter; +var iter, result; function* g() { iter.return(42); } @@ -16,3 +44,9 @@ iter = g(); assert.throws(TypeError, function() { iter.next(); }); + +result = iter.next(); + +assert.sameValue(typeof result, 'object'); +assert.sameValue(result.value, undefined); +assert.sameValue(result.done, true); diff --git a/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js b/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js index 8011b82c88750df3081b2b833d5ea0f04b00d973..a824596d9d1bfdbd11eb288a84acf484e8eaa5bd 100644 --- a/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js +++ b/test/built-ins/GeneratorPrototype/return/from-state-suspended-start.js @@ -8,8 +8,9 @@ description: > state. ---*/ +var bodyCount = 0; function* G() { - yield 1; + bodyCount += 1; } var iter = G(); var result; @@ -18,8 +19,14 @@ result = iter.return(56); assert.sameValue(result.value, 56); assert.sameValue(result.done, true); +assert.sameValue( + bodyCount, 0, 'body not evaluated during processing of `return` method' +); result = iter.next(); assert.sameValue(result.value, undefined, 'Result `value`'); assert.sameValue(result.done, true, 'Result `done` flag'); +assert.sameValue( + bodyCount, 0, 'body not evaluated when "completed" generator is advanced' +); diff --git a/test/built-ins/GeneratorPrototype/return/incorrect-context.js b/test/built-ins/GeneratorPrototype/return/incorrect-context.js deleted file mode 100644 index 17328db8a216970d0115dbcfa293f1ada19e1a4b..0000000000000000000000000000000000000000 --- a/test/built-ins/GeneratorPrototype/return/incorrect-context.js +++ /dev/null @@ -1,17 +0,0 @@ -// 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/this-val-not-generator.js b/test/built-ins/GeneratorPrototype/return/this-val-not-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..b0f0177879d869adbff0bf0e6ccb016d74f37c97 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/this-val-not-generator.js @@ -0,0 +1,69 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.return +es6id: 25.3.1.3 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `return` does not define the [[GeneratorState]] internal slot. +info: | + [...] + 3. Return ? GeneratorResumeAbrupt(g, C). + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + [...] + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call({}); }, + 'ordinary object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call({}, 1); }, + 'ordinary object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(function() {}); }, + 'function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(function() {}, 1); }, + 'function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(g); }, + 'generator function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(g, 1); }, + 'generator function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(g.prototype); }, + 'generator function prototype object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(g.prototype, 1); }, + 'generator function prototype object (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/return/this-val-not-object.js b/test/built-ins/GeneratorPrototype/return/this-val-not-object.js new file mode 100644 index 0000000000000000000000000000000000000000..942991cecfc0dab26b841c0213a0c1ca699bcbb1 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/return/this-val-not-object.js @@ -0,0 +1,91 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.return +es6id: 25.3.1.3 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this" + value of `return` is not an object. +info: | + [...] + 3. Return ? GeneratorResumeAbrupt(g, C). + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. +features: [Symbol] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; +var symbol = Symbol(); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(undefined); }, + 'undefined (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(undefined, 1); }, + 'undefined (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(null); }, + 'null (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(null, 1); }, + 'null (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(true); }, + 'boolean (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(true, 1); }, + 'boolean (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call('s'); }, + 'string (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call('s', 1); }, + 'string (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(1); }, + 'number (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(1, 1); }, + 'number (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(symbol); }, + 'symbol (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.return.call(symbol, 1); }, + 'symbol (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js b/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js index 34a494d19964bfda519d52829fd02e99d65fbf37..6d91d185c8e0f21466a1e001ef81a38b33fd499f 100644 --- a/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js +++ b/test/built-ins/GeneratorPrototype/return/try-catch-before-try.js @@ -8,24 +8,34 @@ description: > location in the function body. ---*/ +var unreachable = 0; function* g() { yield; try { - $ERROR('This code is unreachable (within `try` block)'); + unreachable += 1; } catch (e) { throw e; } - $ERROR('This code is unreachable (following `try` statement)'); + unreachable += 1; } var iter = g(); var result; iter.next(); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (paused at yield)' +); 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( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); + result = iter.next(); assert.sameValue(result.value, undefined, 'Result `value` is undefined when complete' @@ -33,3 +43,6 @@ assert.sameValue(result.value, assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js b/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js index 2e00f0398987d2593ca5bca531510676f606dd9d..1e65a7cb2a8591ebfb091620f37cd726259ac650 100644 --- a/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js +++ b/test/built-ins/GeneratorPrototype/return/try-catch-following-catch.js @@ -8,27 +8,36 @@ description: > location in the function body. ---*/ -var afterCatch = false; +var afterCatch = 0; +var unreachable = 0; function* g() { try { throw new Error(); } catch (e) {} - afterCatch = true; + afterCatch += 1; yield; - $ERROR('This code is unreachable'); + unreachable += 1; } var iter = g(); var result; result = iter.next(); -assert.sameValue(afterCatch, true); +assert.sameValue(afterCatch, 1); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (paused at yield)' +); 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( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -37,3 +46,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js index 4c3648a5eea6b0d8cdddc0329d277036b9505b6e..61e0bed61182b528b565f145b57409fb8794f62a 100644 --- a/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js +++ b/test/built-ins/GeneratorPrototype/return/try-catch-within-catch.js @@ -8,29 +8,35 @@ description: > statement had appeared at that location in the function body. ---*/ -var inCatch = false; +var inCatch = 0; +var unreachable = 0; function* g() { try { throw new Error(); } catch (e) { - inCatch = true; + inCatch += 1; yield; - $ERROR('This code is unreachable (within `catch` block)'); + unreachable += 1; } - $ERROR('This code is unreachable (following `try` statement)'); + unreachable += 1; } var iter = g(); var result; result = iter.next(); -assert.sameValue(inCatch, true); +assert.sameValue(inCatch, 1); 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( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -39,3 +45,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js b/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js index 646785ee9764ed0874192d21a61f6e5d6dd4e903..4e67c78d2a1dca32ca485c879232b0b5515a237c 100644 --- a/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js +++ b/test/built-ins/GeneratorPrototype/return/try-catch-within-try.js @@ -8,27 +8,33 @@ description: > statement had appeared at that location in the function body. ---*/ -var inTry = false; +var inTry = 0; +var unreachable = 0; function* g() { try { - inTry = true; + inTry += 1; yield; - $ERROR('This code is unreachable (within `try` block)'); + unreachable += 1; } catch (e) { throw e; } - $ERROR('This code is unreachable (following `try` statement)'); + unreachable += 1; } var iter = g(); var result; result = iter.next(); -assert.sameValue(inTry, true); +assert.sameValue(inTry, 1); result = iter.return(44); assert.sameValue(result.value, 44, 'Result `value` following `return`'); assert.sameValue(result.done, true, 'Result `done` flag following `return`'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -37,3 +43,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js b/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js index 9da2b4a1d4c836e597c60cdc8e7744f17dda21fc..0dfc83a19ac383112fa3d60d03319fa08408ef2d 100644 --- a/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js +++ b/test/built-ins/GeneratorPrototype/return/try-finally-before-try.js @@ -8,23 +8,32 @@ description: > that location in the function body. ---*/ +var unreachable = 0; function* g() { yield; + unreachable += 1; 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(); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (paused at yield)' +); 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( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -33,3 +42,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js b/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js index 253fc14ef27e8da2c7b45ebb0194c7e5dbbcc1cd..8f6b893147369b0e64fae28b017d4420959950f4 100644 --- a/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js +++ b/test/built-ins/GeneratorPrototype/return/try-finally-following-finally.js @@ -8,26 +8,37 @@ description: > that location in the function body. ---*/ -var afterFinally = false; +var afterFinally = 0; +var unreachable = 0; function* g() { try { } finally {} - afterFinally = true; + afterFinally += 1; yield; + unreachable += 1; } var iter = g(); var result; iter.next(); -assert.sameValue(afterFinally, true); +assert.sameValue(afterFinally, 1); 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( + unreachable, + 0, + 'statement following `yield` not executed (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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); 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 index 96baefa61668b6fc165bc4b1673d075f7ed242fd..0eccc18b30cbdb733605418145b50364dcd01406 100644 --- 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 @@ -9,35 +9,41 @@ description: > function body. ---*/ -var inCatch = false; -var inFinally = false; +var inCatch = 0; +var inFinally = 0; +var unreachable = 0; function* g() { try { try { throw new Error(); } catch (e) { - inCatch = true; + inCatch += 1; yield; - $ERROR('This code is unreachable (within `catch` block)'); + unreachable += 1; } - $ERROR('This code is unreachable (following nested `try` statement)'); + unreachable += 1; } finally { - inFinally = true; + inFinally += 1; } - $ERROR('This code is unreachable (following outer `try` statement)'); + unreachable += 1; } 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'); +assert.sameValue(inCatch, 1, '`catch` code patch executed'); +assert.sameValue(inFinally, 0, '`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'); +assert.sameValue(inFinally, 1, '`finally` code path executed'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -46,3 +52,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when compelete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); 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 index b145c8b70a731025af7d868071b5ebdfcafcf7d1..033e7bfd9ff756a7ffff7c73dfddc8087e48f3fb 100644 --- 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 @@ -8,30 +8,37 @@ description: > statement had appeared at that location in the function body. ---*/ -var inFinally = false; +var inFinally = 0; +var unreachable = 0; function* g() { try { throw new Error(); try { } catch (e) {} } finally { - inFinally = true; + inFinally += 1; yield; - $ERROR('This code is unreachable (within `finally` block)'); + unreachable += 1; } - $ERROR('This code is unreachable (following outer `try` statement)'); + unreachable += 1; } var iter = g(); var result; result = iter.next(); -assert.sameValue(inFinally, true, '`finally` code path executed'); +assert.sameValue(inFinally, 1, '`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`'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); + result = iter.next(); assert.sameValue( result.value, undefined, 'Result `value` is undefined when complete' @@ -39,3 +46,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); 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 index 99a3e5ab370c4be553d5412b66e07d85a7ddcb0b..2c3e9e94d9427e7a3fb1b565350e96c633a61bec 100644 --- 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 @@ -9,37 +9,43 @@ description: > function body. ---*/ -var inTry = false; -var inFinally = false; +var inTry = 0; +var inFinally = 0; +var unreachable = 0; function* g() { try { try { - inTry = true; + inTry += 1; yield; - $ERROR('This code is unreachable (within nested `try` block)'); + unreachable += 1; } catch (e) { throw e; } - $ERROR('This code is unreachable (following nested `try` statement)'); + unreachable += 1; } finally { - inFinally = true; + inFinally += 1; } - $ERROR('This code is unreachable (following outer `try` statement)'); + unreachable += 1; } 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'); +assert.sameValue(inTry, 1, 'Nested `try` code patch executed'); +assert.sameValue(inFinally, 0, '`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'); +assert.sameValue(inFinally, 1, '`finally` code path executed'); + +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -48,3 +54,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); 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 index 15d4fa1f240670c0de63034fa05d523ad1f2fd1c..c30896370fc0e59f64c87f429af1e481cd2b048e 100644 --- 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 @@ -9,33 +9,40 @@ description: > the function body. ---*/ -var inCatch = false; -var inFinally = false; +var inCatch = 0; +var inFinally = 0; +var unreachable = 0; function* g() { try { try { throw new Error(); } catch (e) { - inCatch = true; + inCatch += 1; } } finally { - inFinally = true; + inFinally += 1; } yield; - $ERROR('This code is unreachable'); + unreachable += 1; } var iter = g(); var result; iter.next(); -assert.sameValue(inCatch, true, '`catch` code path executed'); -assert.sameValue(inFinally, true, '`finally` code path executed'); +assert.sameValue(inCatch, 1, '`catch` code path executed'); +assert.sameValue(inFinally, 1, '`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`'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); + result = iter.next(); assert.sameValue( result.value, undefined, 'Result `value` is undefined when complete' @@ -43,3 +50,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); 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 index 5e4b87999c859a286440b0e1c8707697dbb738b1..d47c5f9e63e5446cc94aac4c22b326d1a93eb264 100644 --- 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 @@ -9,35 +9,42 @@ description: > the function body. ---*/ -var inTry = false; -var inFinally = false; +var inTry = 0; +var inFinally = 0; +var unreachable = 0; function* g() { try { - inTry = true; + inTry += 1; yield; try { - $ERROR('This code is unreachable (within nested `try` block)'); + unreachable += 1; } catch (e) { throw e; } - $ERROR('This code is unreacahable (following nested `try` statement)'); + unreachable += 1; } finally { - inFinally = true; + inFinally += 1; } - $ERROR('This codeis unreachable (following outer `try` statement)'); + unreachable += 1; } var iter = g(); var result; iter.next(); -assert.sameValue(inTry, true, '`try` code path executed'); -assert.sameValue(inFinally, false, '`finally` code path not executed'); +assert.sameValue(inTry, 1, '`try` code path executed'); +assert.sameValue(inFinally, 0, '`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'); +assert.sameValue(inFinally, 1, '`finally` code path executed'); + +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -46,3 +53,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js b/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js index ae0b022c58d9dcbd00b3e83c2f32794da9de9b8f..738a2c0c166df72e4aacc9ae11f03f9f043b3ffc 100644 --- a/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js +++ b/test/built-ins/GeneratorPrototype/return/try-finally-within-finally.js @@ -8,27 +8,34 @@ description: > statement had appeared at that location in the function body. ---*/ -var inFinally = true; +var inFinally = 0; +var unreachable = 0; function* g() { try { } finally { - inFinally = true; + inFinally += 1; yield; - $ERROR('This code is unreachable (within `finally` block)'); + unreachable += 1; } - $ERROR('This code is unreachable (following `try` statement)'); + unreachable += 1; } var iter = g(); var result; iter.next(); -assert.sameValue(inFinally, true, '`finally` code path executed'); +assert.sameValue(inFinally, 1, '`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`'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); + result = iter.next(); assert.sameValue( result.value, undefined, 'Result `value` is undefined when complete' @@ -36,3 +43,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js b/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js index 6a098be79d0c7643ddb723568a509310de012ac5..829bf00aa7809841a203d21357583d2e6e563e1d 100644 --- a/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js +++ b/test/built-ins/GeneratorPrototype/return/try-finally-within-try.js @@ -8,30 +8,37 @@ description: > statement had appeared at that location in the function body. ---*/ -var inTry = false; -var inFinally = false; +var inTry = 0; +var inFinally = 0; +var unreachable = 0; function* g() { try { - inTry = true; + inTry += 1; yield; - $ERROR('This code is unreachable (within `try` block)'); + unreachable += 1; } finally { - inFinally = true; + inFinally += 1; } - $ERROR('This code is unreachable (following `try` statement)'); + unreachable += 1; } 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'); +assert.sameValue(inTry, 1, '`try` block code path executed'); +assert.sameValue(inFinally, 0, '`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'); +assert.sameValue(inFinally, 1, '`finally` code path executed'); + +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `return`)' +); result = iter.next(); assert.sameValue( @@ -40,3 +47,6 @@ assert.sameValue( assert.sameValue( result.done, true, 'Result `done` flag is `true` when complete' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); diff --git a/test/built-ins/GeneratorPrototype/throw/from-state-executing.js b/test/built-ins/GeneratorPrototype/throw/from-state-executing.js index 546ef91040b58260832284a36016c5d741fa4965..76c05ea91a32d6c0bff313b85e0fd512a1c90d6c 100644 --- a/test/built-ins/GeneratorPrototype/throw/from-state-executing.js +++ b/test/built-ins/GeneratorPrototype/throw/from-state-executing.js @@ -1,13 +1,41 @@ // Copyright (C) 2013 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: sec-generatorvalidate es6id: 25.3.3.2 description: > - A TypeError should be thrown if the generator is resumed abruptly while - running. + A TypeError should be thrown if the generator is in the "executing" state, + and the generator should be marked as "completed" +info: | + 25.3.3.1 GeneratorStart + + [...] + 4. Set the code evaluation state of genContext such that when evaluation is + resumed for that execution context the following steps will be performed: + a. Let result be the result of evaluating generatorBody. + b. Assert: If we return here, the generator either threw an exception or + performed either an implicit or explicit return. + c. Remove genContext from the execution context stack and restore the + execution context that is at the top of the execution context stack as + the running execution context. + d. Set generator.[[GeneratorState]] to "completed". + [...] + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. + 3. Assert: generator also has a [[GeneratorContext]] internal slot. + 4. Let state be generator.[[GeneratorState]]. + 5. If state is "executing", throw a TypeError exception. ---*/ -var iter; +var iter, result; function* g() { iter.throw(42); } @@ -16,3 +44,9 @@ iter = g(); assert.throws(TypeError, function() { iter.next(); }); + +result = iter.next(); + +assert.sameValue(typeof result, 'object'); +assert.sameValue(result.value, undefined); +assert.sameValue(result.done, true); diff --git a/test/built-ins/GeneratorPrototype/throw/incorrect-context.js b/test/built-ins/GeneratorPrototype/throw/incorrect-context.js deleted file mode 100644 index 827292acbbd79c43a2d0ae191ed0d689018dc4b0..0000000000000000000000000000000000000000 --- a/test/built-ins/GeneratorPrototype/throw/incorrect-context.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2013 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -es6id: 25.3.1.4 -description: > - A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the - context of `throw` does not defined the [[GeneratorState]] internal slot. ----*/ - -function* g() {} -var GeneratorPrototype = Object.getPrototypeOf(g).prototype; - -assert.throws(TypeError, function() { GeneratorPrototype.throw.call(1); }); -assert.throws(TypeError, function() { GeneratorPrototype.throw.call({}); }); -assert.throws(TypeError, function() { GeneratorPrototype.throw.call(function() {}); }); -assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g); }); -assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g.prototype); }); diff --git a/test/built-ins/GeneratorPrototype/throw/this-val-not-generator.js b/test/built-ins/GeneratorPrototype/throw/this-val-not-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..cfdf1deb4b4a9ebef82d8ca9ab8d4e667c2547ee --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/this-val-not-generator.js @@ -0,0 +1,69 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.throw +es6id: 25.3.1.4 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `throw` does not define the [[GeneratorState]] internal slot. +info: | + [...] + 3. Return ? GeneratorResumeAbrupt(g, C). + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + [...] + 2. If generator does not have a [[GeneratorState]] internal slot, throw a + TypeError exception. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call({}); }, + 'ordinary object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call({}, 1); }, + 'ordinary object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(function() {}); }, + 'function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(function() {}, 1); }, + 'function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(g); }, + 'generator function object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(g, 1); }, + 'generator function object (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(g.prototype); }, + 'generator function prototype object (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(g.prototype, 1); }, + 'generator function prototype object (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/throw/this-val-not-object.js b/test/built-ins/GeneratorPrototype/throw/this-val-not-object.js new file mode 100644 index 0000000000000000000000000000000000000000..945798405ce7ad73728a9405960218759dc6e280 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/this-val-not-object.js @@ -0,0 +1,91 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-generator.prototype.throw +es6id: 25.3.1.4 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this" + value of `throw` is not an object. +info: | + [...] + 3. Return ? GeneratorResumeAbrupt(g, C). + + 25.3.3.4 GeneratorResumeAbrupt + + 1. Let state be ? GeneratorValidate(generator). + + 25.3.3.2 GeneratorValidate + + 1. If Type(generator) is not Object, throw a TypeError exception. +features: [Symbol] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; +var symbol = Symbol(); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(undefined); }, + 'undefined (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(undefined, 1); }, + 'undefined (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(null); }, + 'null (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(null, 1); }, + 'null (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(true); }, + 'boolean (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(true, 1); }, + 'boolean (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call('s'); }, + 'string (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call('s', 1); }, + 'string (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(1); }, + 'number (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(1, 1); }, + 'number (with value)' +); + +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(symbol); }, + 'symbol (without value)' +); +assert.throws( + TypeError, + function() { GeneratorPrototype.throw.call(symbol, 1); }, + 'symbol (with value)' +); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js b/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js index 3b5f7d13a986f5e18f0ddb64ecbf66c769d83368..968cd39b1a1cf3505091f0b45c63a1bb0a448069 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js @@ -8,8 +8,10 @@ description: > location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; + unreachable += 1; try { yield 2; } catch (e) { @@ -17,19 +19,32 @@ function* g() { } yield 3; } -var iter, result, exception; +var iter, result; iter = g(); result = iter.next(); assert.sameValue(result.value, 1, 'First result `value`'); assert.sameValue(result.done, false, 'First result `done` flag'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (paused at yield)' +); + assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); 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 5da206774c57631bebc313d061ff0c7c5e29aeb0..c358765e4e3a284aa60e70be3ba7d5631a8b99aa 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js @@ -9,6 +9,7 @@ description: > ---*/ var obj = {}; +var unreachable = 0; function* g() { yield 1; try { @@ -18,6 +19,7 @@ function* g() { yield e; } yield 3; + unreachable += 1; } var iter, result; @@ -40,10 +42,19 @@ assert.sameValue(result.done, false, 'Fourth result `done` flag'); assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js index 9e2329e9d48decd754bf07a65579f40066ed8f0e..a5329ad4277f0b3982bbf6facaa3b7101cc759c7 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js @@ -8,6 +8,7 @@ description: > had appeared at that location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; try { @@ -15,6 +16,7 @@ function* g() { throw exception; } catch (e) { yield e; + unreachable += 1; } yield 3; } @@ -35,15 +37,21 @@ result = iter.next(); assert.sameValue(result.value, exception, 'Third result `value`'); assert.sameValue(result.done, false, 'Third result `done` flag'); -result = iter.next(); -assert.sameValue(result.value, 3, 'Fourth result `value`'); -assert.sameValue(result.done, false, 'Fourth result `done` flag'); assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js b/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js index b768c3860c3bebd248a43e2869e4ec92b3516613..56920f99496deabaf28a7b4191785890e33fb80b 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js @@ -8,10 +8,12 @@ description: > had appeared at that location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; try { yield 2; + unreachable += 1; } catch (e) { yield e; } @@ -34,14 +36,28 @@ result = iter.throw(exception); assert.sameValue(result.value, exception, 'Third result `value`'); assert.sameValue(result.done, false, 'Third result `done` flag'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + result = iter.next(); assert.sameValue(result.value, 3, 'Fourth result `done` flag'); assert.sameValue(result.done, false, 'Fourth result `value`'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `catch`)' +); 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js index 87518726bab254c3be303fb810e86c05b96cdbd1..f0859a57691c0dc2d2185fe34469eb743ab70fd3 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js @@ -8,8 +8,10 @@ description: > that location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; + unreachable += 1; try { yield 2; } finally { @@ -26,13 +28,25 @@ assert.sameValue(result.value, 1, 'First result `value`'); assert.sameValue( result.done, false, 'First result `done` flag' ); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (paused at yield)' +); assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js index 0c7c06101943cba69dcd0245145432706bc9aae8..d4b894ec044bf378d35599fdf17ac436fc47eadb 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js @@ -8,6 +8,7 @@ description: > location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; try { @@ -16,7 +17,7 @@ function* g() { yield 3; } yield 4; - $ERROR('This code is unreachable'); + unreachable += 1; } var iter = g(); var result; @@ -39,10 +40,19 @@ assert.sameValue(result.done, false, 'Third result `done` flag'); assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js index abc3466dd31f8658a43fa6641e73b50752b1265b..edbb9d2ee65caee344812b9162cb10443e206252 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js @@ -9,6 +9,7 @@ description: > function body. ---*/ +var unreachable = 0; function* g() { try { yield 1; @@ -17,6 +18,7 @@ function* g() { throw exception; } catch (e) { yield e; + unreachable += 1; } yield 3; } finally { @@ -46,10 +48,19 @@ assert.sameValue(result.done, false, 'Fourth result `done` flag'); assert.throws(Test262Error, function() { iter.next(); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js index 8c3ec7377aae09727acad913ed08bcaa99c64c79..7042aab6202e447158b73dabac614f931958aa6f 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js @@ -8,6 +8,7 @@ description: > had appeared at that location in the function body. ---*/ +var unreachable = 0; function* g() { try { yield 1; @@ -20,7 +21,9 @@ function* g() { yield 3; } finally { yield 4; + unreachable += 1; } + unreachable += 1; yield 5; } var iter = g(); @@ -36,10 +39,19 @@ assert.sameValue(result.done, false, 'First result `done` flag'); assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js index 38a40083d41b106112f167dee73586c976d79d88..13ea93f04be6b50f7be6fee3a2dda44ec668d590 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js @@ -9,11 +9,13 @@ description: > function body. ---*/ +var unreachable = 0; function* g() { try { yield 1; try { yield 2; + unreachable += 1; } catch (e) { yield e; } @@ -39,6 +41,12 @@ result = iter.throw(exception); assert.sameValue(result.value, exception, 'Third result `value`'); assert.sameValue(result.done, false, 'Third result `done` flag'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + result = iter.next(); assert.sameValue(result.value, 3, 'Fourth result `value'); assert.sameValue(result.done, false, 'Fourth result `done` flag'); @@ -56,5 +64,8 @@ assert.sameValue( result.value, undefined, 'Result `value` is undefined when done' ); assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js index f5d8d5f5f862ed49ff4664477d673fad32f83ce8..0f0145696d6c837a35ed5220de14631d8687e238 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js @@ -9,6 +9,7 @@ description: > function body. ---*/ +var unreachable = 0; function* g() { try { yield 1; @@ -19,6 +20,7 @@ function* g() { yield e; } yield 3; + unreachable += 1; } finally { yield 4; } @@ -48,6 +50,12 @@ result = iter.throw(new Test262Error()); assert.sameValue(result.value, 4, 'Fifth result `value`'); assert.sameValue(result.done, false, 'Fifth result `done` flag'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + assert.throws(Test262Error, function() { iter.next(); }); result = iter.next(); @@ -55,5 +63,8 @@ assert.sameValue( result.value, undefined, 'Result `value` is undefined when done' ); assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js index aaee09693052f823b8b36f41f1337b729d1021c8..70a1caa642e67bd63d87ead99d2b9f4f6723b58d 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js @@ -9,9 +9,11 @@ description: > function body. ---*/ +var unreachable = 0; function* g() { try { yield 1; + unreachable += 1; try { yield 2; } catch (e) { @@ -34,6 +36,12 @@ result = iter.throw(new Test262Error()); assert.sameValue(result.value, 4, 'Second result `value`'); assert.sameValue(result.done, false, 'Second result `done` flag'); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + assert.throws(Test262Error, function() { iter.next(); }); result = iter.next(); @@ -41,5 +49,8 @@ assert.sameValue( result.value, undefined, 'Result `value` is undefined when done' ); assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js index 1345eeaee9e4599e3ec364749acca2d975acf2ce..47660bfbb4965d00ecc49e7fd5b01a7d48e6c6ac 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js @@ -8,12 +8,14 @@ description: > had appeared at that location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; try { yield 2; } finally { yield 3; + unreachable += 1; } yield 4; } @@ -32,16 +34,21 @@ result = iter.next(); assert.sameValue(result.value, 3, 'Third result `value`'); assert.sameValue(result.done, false, 'Third result `done` flag'); -result = iter.next(); -assert.sameValue(result.value, 4, 'Fourth result `value`'); -assert.sameValue(result.done, false, 'Fourth result `done` flag'); - assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js index d7c28f8b3b34c33d28b46d906c015da2d9d403dc..0fb83361399f3e1563f9cabcd724ae09165aff3a 100644 --- a/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js @@ -8,10 +8,12 @@ description: > had appeared at that location in the function body. ---*/ +var unreachable = 0; function* g() { yield 1; try { yield 2; + unreachable += 1; } finally { yield 3; } @@ -28,16 +30,25 @@ result = iter.next(); assert.sameValue(result.value, 2, 'Second result `value`'); assert.sameValue(result.done, false, 'Second result `done` flag'); -result = iter.next(); +result = iter.throw(new Test262Error()); assert.sameValue(result.value, 3, 'Third result `value`'); assert.sameValue(result.done, false, 'Third result `done` flag'); -assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); +assert.sameValue( + unreachable, + 0, + 'statement following `yield` not executed (following `throw`)' +); + +assert.throws(Test262Error, function() { iter.next(); }); 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'); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); iter.next();