diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/built-ins/GeneratorPrototype | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/GeneratorPrototype')
68 files changed, 3126 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/Symbol.toStringTag.js b/js/src/tests/test262/built-ins/GeneratorPrototype/Symbol.toStringTag.js new file mode 100644 index 0000000000..5267d8a387 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/Symbol.toStringTag.js @@ -0,0 +1,28 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + `Symbol.toStringTag` property descriptor +info: | + The initial value of the @@toStringTag property is the String value + "Generator". + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +es6id: 25.3.1.5 +includes: [propertyHelper.js] +features: [generators, Symbol.toStringTag] +---*/ + +var GeneratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf(function*() {}()) +); + +assert.sameValue(GeneratorPrototype[Symbol.toStringTag], 'Generator'); + +verifyNotEnumerable(GeneratorPrototype, Symbol.toStringTag); +verifyNotWritable(GeneratorPrototype, Symbol.toStringTag); +verifyConfigurable(GeneratorPrototype, Symbol.toStringTag); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/browser.js b/js/src/tests/test262/built-ins/GeneratorPrototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/browser.js diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/constructor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/constructor.js new file mode 100644 index 0000000000..1c6e3345d7 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/constructor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2013 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 `constructor` property + that is non-enumerable, non-writable, and configurable. +includes: [propertyHelper.js] +es6id: 25.3.1 +features: [generators] +---*/ + +function* g() {} +var Generator = Object.getPrototypeOf(g); +var GeneratorPrototype = Generator.prototype; + +assert.sameValue(GeneratorPrototype.constructor, Generator); + +verifyNotEnumerable(GeneratorPrototype, 'constructor'); +verifyNotWritable(GeneratorPrototype, 'constructor'); +verifyConfigurable(GeneratorPrototype, 'constructor'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/browser.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/browser.js diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/consecutive-yields.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/consecutive-yields.js new file mode 100644 index 0000000000..9d4c42d14a --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/consecutive-yields.js @@ -0,0 +1,30 @@ +// 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.2 +description: > + When a generator body contains two consecutive yield statements, it should + produce an iterable that visits each yielded value and then completes. +features: [generators] +---*/ + +function* g() { + yield 1; + yield 2; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Third result `value`'); +assert.sameValue(result.done, true, 'Third result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/context-method-invocation.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/context-method-invocation.js new file mode 100644 index 0000000000..78cdd3f970 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/context-method-invocation.js @@ -0,0 +1,25 @@ +// 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.2 +description: > + When a generator function is invoked as a method of an object, its context + is that object. +features: [generators] +---*/ + +var context; + +function* g() { + context = this; +} +var obj = { + g: g +}; +var iter = obj.g(); + +iter.next(); + +assert.sameValue(context, obj); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/from-state-executing.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/from-state-executing.js new file mode 100644 index 0000000000..1ea8661dfe --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/from-state-executing.js @@ -0,0 +1,82 @@ +// 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 +description: > + 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. +features: [generators] +---*/ + +var iter, result; + +function* withoutVal() { + iter.next(); +} + +function* withVal() { + iter.next(42); +} + +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' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/length.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/length.js new file mode 100644 index 0000000000..d4bbe4aaad --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/length.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.2 +description: > + Generator.prototype.next.length is 1. +info: | + Generator.prototype.next ( value ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description, including optional + parameters. However, rest parameters shown using the form “...name” + are not included in the default argument count. + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.next.length, 1); + +verifyNotEnumerable(GeneratorPrototype.next, "length"); +verifyNotWritable(GeneratorPrototype.next, "length"); +verifyConfigurable(GeneratorPrototype.next, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-return.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-return.js new file mode 100644 index 0000000000..9af01b5f94 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-return.js @@ -0,0 +1,21 @@ +// 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.2 +description: > + When a generator body contains a lone return statement, it should produce + an iterator that immediately completes with the returned value. +features: [generators] +---*/ + +function* g() { + return 23; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 23, 'Result value'); +assert.sameValue(result.done, true, 'Result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-yield.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-yield.js new file mode 100644 index 0000000000..e0e6e67d29 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/lone-yield.js @@ -0,0 +1,25 @@ +// 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.2 +description: > + When a generator body contains a lone yield statement, it should produce an + iterable that visits the yielded value and then completes. +features: [generators] +---*/ + +function* g() { + yield 1; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/name.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/name.js new file mode 100644 index 0000000000..e52239af1a --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/name.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.2 +description: > + Generator.prototype.next.name is "next". +info: | + Generator.prototype.next ( value ) + + 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] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.next.name, "next"); + +verifyNotEnumerable(GeneratorPrototype.next, "name"); +verifyNotWritable(GeneratorPrototype.next, "name"); +verifyConfigurable(GeneratorPrototype.next, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/no-control-flow.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/no-control-flow.js new file mode 100644 index 0000000000..8d03463ff5 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/no-control-flow.js @@ -0,0 +1,24 @@ +// 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.2 +description: > + When a generator body contains no control flow statements, it should + produce an iterator that is initially completed with `undefined` as its + value. +features: [generators] +---*/ + +function* g() {} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, undefined, 'First result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/not-a-constructor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/not-a-constructor.js new file mode 100644 index 0000000000..49865588f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/not-a-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Object.getPrototypeOf((function* g() {}).prototype).next does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, generators, arrow-function] +---*/ + +assert.sameValue( + isConstructor(Object.getPrototypeOf((function* g() {}).prototype).next), + false, + 'isConstructor(Object.getPrototypeOf((function* g() {}).prototype).next) must return false' +); + +assert.throws(TypeError, () => { + function* g() {} let iterator = g(); new iterator.next(); +}, '`function* g() {} let iterator = g(); new iterator.next()` throws TypeError'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/property-descriptor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/property-descriptor.js new file mode 100644 index 0000000000..cf5600f0e4 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/property-descriptor.js @@ -0,0 +1,20 @@ +// Copyright (C) 2013 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 `next` property that is + non-enumerable, writable, and configurable (as per section 17). +includes: [propertyHelper.js] +es6id: 25.3.1 +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'next'); +verifyWritable(GeneratorPrototype, 'next'); +verifyConfigurable(GeneratorPrototype, 'next'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/result-prototype.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/result-prototype.js new file mode 100644 index 0000000000..dfe0596ee5 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/result-prototype.js @@ -0,0 +1,22 @@ +// 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.2 +description: > + The `next` method returns an object that has "own" properties `value` and + `done` and that inherits directly from the Object prototype. +features: [generators] +---*/ + +function* g() {} +var result = g().next(); + +assert( + Object.prototype.hasOwnProperty.call(result, 'value'), 'Has "own" property `value`' +); +assert( + Object.prototype.hasOwnProperty.call(result, 'done'), 'Has "own" property `done`' +); +assert.sameValue(Object.getPrototypeOf(result), Object.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/return-yield-expr.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/return-yield-expr.js new file mode 100644 index 0000000000..278e19d868 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/return-yield-expr.js @@ -0,0 +1,24 @@ +// 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.2 +description: > + Yield expressions are valid yield expression operands. +features: [generators] +---*/ + +function* g() { + return yield 1; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(3); +assert.sameValue(result.value, 3, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/shell.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-generator.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-generator.js new file mode 100644 index 0000000000..d19ea6c2d9 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-generator.js @@ -0,0 +1,87 @@ +// 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 +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. +features: [generators] +---*/ + +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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-object.js b/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-object.js new file mode 100644 index 0000000000..4dc17a7e3e --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/next/this-val-not-object.js @@ -0,0 +1,116 @@ +// 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 +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: [generators, 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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/browser.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/browser.js diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-completed.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-completed.js new file mode 100644 index 0000000000..fc4f0d7232 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-completed.js @@ -0,0 +1,27 @@ +// 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. +features: [generators] +---*/ + +function* G() {} +var iter, result; + +iter = G(); +iter.next(); + +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, 'next: result `value`'); +assert.sameValue(result.done, true, 'next: result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-executing.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-executing.js new file mode 100644 index 0000000000..62827d5ad6 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-executing.js @@ -0,0 +1,54 @@ +// 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 +description: > + 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. +features: [generators] +---*/ + +var iter, result; +function* g() { + iter.return(42); +} + +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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-suspended-start.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-suspended-start.js new file mode 100644 index 0000000000..0fcea2890c --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/from-state-suspended-start.js @@ -0,0 +1,35 @@ +// 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. +features: [generators] +---*/ + +var bodyCount = 0; +function* G() { + bodyCount += 1; +} +var iter = G(); +var result; + +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' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/length.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/length.js new file mode 100644 index 0000000000..a3f8f38369 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/length.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.3 +description: > + Generator.prototype.return.length is 1. +info: | + Generator.prototype.return ( value ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description, including optional + parameters. However, rest parameters shown using the form “...name” + are not included in the default argument count. + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.return.length, 1); + +verifyNotEnumerable(GeneratorPrototype.return, "length"); +verifyNotWritable(GeneratorPrototype.return, "length"); +verifyConfigurable(GeneratorPrototype.return, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/name.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/name.js new file mode 100644 index 0000000000..e1b4512522 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/name.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.3 +description: > + Generator.prototype.return.name is "return". +info: | + Generator.prototype.return ( value ) + + 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] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.return.name, "return"); + +verifyNotEnumerable(GeneratorPrototype.return, "name"); +verifyNotWritable(GeneratorPrototype.return, "name"); +verifyConfigurable(GeneratorPrototype.return, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/not-a-constructor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/not-a-constructor.js new file mode 100644 index 0000000000..4c0f2b56b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/not-a-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Object.getPrototypeOf((function* g() {}).prototype).return does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, generators, arrow-function] +---*/ + +assert.sameValue( + isConstructor(Object.getPrototypeOf((function* g() {}).prototype).return), + false, + 'isConstructor(Object.getPrototypeOf((function* g() {}).prototype).return) must return false' +); + +assert.throws(TypeError, () => { + function* g() {} let iterator = g(); new iterator.return(); +}, '`function* g() {} let iterator = g(); new iterator.return()` throws TypeError'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/property-descriptor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/property-descriptor.js new file mode 100644 index 0000000000..44b776bd62 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/property-descriptor.js @@ -0,0 +1,20 @@ +// 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 +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'return'); +verifyWritable(GeneratorPrototype, 'return'); +verifyConfigurable(GeneratorPrototype, 'return'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/shell.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-generator.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-generator.js new file mode 100644 index 0000000000..c580949bcc --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-generator.js @@ -0,0 +1,87 @@ +// 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 +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. +features: [generators] +---*/ + +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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-object.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-object.js new file mode 100644 index 0000000000..707d11e5e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/this-val-not-object.js @@ -0,0 +1,116 @@ +// 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 +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: [generators, 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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-before-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-before-try.js new file mode 100644 index 0000000000..b269830153 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-before-try.js @@ -0,0 +1,51 @@ +// 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. +features: [generators] +---*/ + +var unreachable = 0; +function* g() { + yield; + try { + unreachable += 1; + } catch (e) { + throw e; + } + 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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-following-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-following-catch.js new file mode 100644 index 0000000000..a372e7dce4 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-following-catch.js @@ -0,0 +1,54 @@ +// 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. +features: [generators] +---*/ + +var afterCatch = 0; +var unreachable = 0; +function* g() { + try { + throw new Error(); + } catch (e) {} + afterCatch += 1; + yield; + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); + +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( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-catch.js new file mode 100644 index 0000000000..9f9528b45a --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-catch.js @@ -0,0 +1,53 @@ +// 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. +features: [generators] +---*/ + +var inCatch = 0; +var unreachable = 0; +function* g() { + try { + throw new Error(); + } catch (e) { + inCatch += 1; + yield; + unreachable += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); + +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( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-try.js new file mode 100644 index 0000000000..97c4a29cc1 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-catch-within-try.js @@ -0,0 +1,51 @@ +// 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. +features: [generators] +---*/ + +var inTry = 0; +var unreachable = 0; +function* g() { + try { + inTry += 1; + yield; + unreachable += 1; + } catch (e) { + throw e; + } + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); + +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( + result.value, undefined, 'Result `value` is undefined when complete' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-before-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-before-try.js new file mode 100644 index 0000000000..a2ef016769 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-before-try.js @@ -0,0 +1,49 @@ +// 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. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield; + unreachable += 1; + try {} finally {} +} +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-following-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-following-finally.js new file mode 100644 index 0000000000..9e185e5257 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-following-finally.js @@ -0,0 +1,47 @@ +// 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. +features: [generators] +---*/ + +var afterFinally = 0; +var unreachable = 0; + +function* g() { + try {} finally {} + afterFinally += 1; + yield; + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js new file mode 100644 index 0000000000..86a8580e7f --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-catch.js @@ -0,0 +1,60 @@ +// 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. +features: [generators] +---*/ + +var inCatch = 0; +var inFinally = 0; +var unreachable = 0; +function* g() { + try { + try { + throw new Error(); + } catch (e) { + inCatch += 1; + yield; + unreachable += 1; + } + unreachable += 1; + } finally { + inFinally += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); + +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, 1, '`finally` code path executed'); +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when compelete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js new file mode 100644 index 0000000000..f810d8e82d --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-finally.js @@ -0,0 +1,54 @@ +// 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. +features: [generators] +---*/ + +var inFinally = 0; +var unreachable = 0; + +function* g() { + try { + throw new Error(); + try {} catch (e) {} + } finally { + inFinally += 1; + yield; + unreachable += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js new file mode 100644 index 0000000000..b011444a4f --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-inner-try.js @@ -0,0 +1,62 @@ +// 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. +features: [generators] +---*/ + +var inTry = 0; +var inFinally = 0; +var unreachable = 0; +function* g() { + try { + try { + inTry += 1; + yield; + unreachable += 1; + } catch (e) { + throw e; + } + unreachable += 1; + } finally { + inFinally += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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, 1, '`finally` code path executed'); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js new file mode 100644 index 0000000000..a86a1ffa7c --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-after-nested.js @@ -0,0 +1,59 @@ +// 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. +features: [generators] +---*/ + +var inCatch = 0; +var inFinally = 0; +var unreachable = 0; + +function* g() { + try { + try { + throw new Error(); + } catch (e) { + inCatch += 1; + } + } finally { + inFinally += 1; + } + yield; + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js new file mode 100644 index 0000000000..1e59fe4c96 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-nested-try-catch-within-outer-try-before-nested.js @@ -0,0 +1,61 @@ +// 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. +features: [generators] +---*/ + +var inTry = 0; +var inFinally = 0; +var unreachable = 0; +function* g() { + try { + inTry += 1; + yield; + try { + unreachable += 1; + } catch (e) { + throw e; + } + unreachable += 1; + } finally { + inFinally += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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, 1, '`finally` code path executed'); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-finally.js new file mode 100644 index 0000000000..967955e79f --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-finally.js @@ -0,0 +1,51 @@ +// 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. +features: [generators] +---*/ + +var inFinally = 0; +var unreachable = 0; + +function* g() { + try {} finally { + inFinally += 1; + yield; + unreachable += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-try.js new file mode 100644 index 0000000000..7edcd27b88 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/return/try-finally-within-try.js @@ -0,0 +1,55 @@ +// 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. +features: [generators] +---*/ + +var inTry = 0; +var inFinally = 0; +var unreachable = 0; +function* g() { + try { + inTry += 1; + yield; + unreachable += 1; + } finally { + inFinally += 1; + } + unreachable += 1; +} +var iter = g(); +var result; + +iter.next(); + +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, 1, '`finally` code path executed'); + +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' +); +assert.sameValue( + result.done, true, 'Result `done` flag is `true` when complete' +); +assert.sameValue( + unreachable, 0, 'statement following `yield` not executed (once "completed")' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/shell.js b/js/src/tests/test262/built-ins/GeneratorPrototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/shell.js diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/browser.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/browser.js diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-completed.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-completed.js new file mode 100644 index 0000000000..1397438454 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-completed.js @@ -0,0 +1,28 @@ +// 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.4 +description: > + Resuming abruptly from a generator in the 'completed' state should honor + the abrupt completion and remain in the 'completed' state. +features: [generators] +---*/ + +function E() {} + +function* G() {} +var iter; + +iter = G(); +iter.next(); + +assert.throws(E, function() { + iter.throw(new E()); +}); + +var result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-executing.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-executing.js new file mode 100644 index 0000000000..ac7685409e --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-executing.js @@ -0,0 +1,54 @@ +// 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 +description: > + 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. +features: [generators] +---*/ + +var iter, result; +function* g() { + iter.throw(42); +} + +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); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js new file mode 100644 index 0000000000..cadfc63eaf --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js @@ -0,0 +1,30 @@ +// 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.4 +description: > + Resuming abruptly from a generator in the 'suspendedStart' state should + honor the abrupt completion and trigger a transition into the 'completed' + state. +features: [generators] +---*/ + +function E() {} + +function* G() { + yield 1; + yield 2; +} +var iter; + +iter = G(); +assert.throws(E, function() { + iter.throw(new E()); +}); + +var result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/length.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/length.js new file mode 100644 index 0000000000..75c2f6b2a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/length.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.4 +description: > + Generator.prototype.throw.length is 1. +info: | + Generator.prototype.throw ( exception ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description, including optional + parameters. However, rest parameters shown using the form “...name” + are not included in the default argument count. + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.throw.length, 1); + +verifyNotEnumerable(GeneratorPrototype.throw, "length"); +verifyNotWritable(GeneratorPrototype.throw, "length"); +verifyConfigurable(GeneratorPrototype.throw, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/name.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/name.js new file mode 100644 index 0000000000..d167bbc1cc --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/name.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.3.1.4 +description: > + Generator.prototype.throw.name is "throw". +info: | + Generator.prototype.throw ( exception ) + + 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] +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.sameValue(GeneratorPrototype.throw.name, "throw"); + +verifyNotEnumerable(GeneratorPrototype.throw, "name"); +verifyNotWritable(GeneratorPrototype.throw, "name"); +verifyConfigurable(GeneratorPrototype.throw, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/not-a-constructor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/not-a-constructor.js new file mode 100644 index 0000000000..d8d39a4db5 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/not-a-constructor.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Object.getPrototypeOf((function* g() {}).prototype).throw does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, generators, arrow-function] +---*/ + +assert.sameValue( + isConstructor(Object.getPrototypeOf((function* g() {}).prototype).throw), + false, + 'isConstructor(Object.getPrototypeOf((function* g() {}).prototype).throw) must return false' +); + +assert.throws(TypeError, () => { + function* g() {} let expected = new Test262Error(); let iterator = g();try {new iterator.throw(expected);} catch (e) {if (e !== expected) {throw e;}} +}, '`function* g() {} let expected = new Test262Error(); let iterator = g();try {new iterator.throw(expected);} catch (e) {if (e !== expected) {throw e;}}` throws TypeError'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/property-descriptor.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/property-descriptor.js new file mode 100644 index 0000000000..e67b04d033 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/property-descriptor.js @@ -0,0 +1,20 @@ +// Copyright (C) 2013 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 `throw` property that is + non-enumerable, writable, and configurable (as per section 17). +includes: [propertyHelper.js] +es6id: 25.3.1 +features: [generators] +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'throw'); +verifyWritable(GeneratorPrototype, 'throw'); +verifyConfigurable(GeneratorPrototype, 'throw'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/shell.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-generator.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-generator.js new file mode 100644 index 0000000000..cf6d223323 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-generator.js @@ -0,0 +1,87 @@ +// 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 +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. +features: [generators] +---*/ + +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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-object.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-object.js new file mode 100644 index 0000000000..9a460c28f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/this-val-not-object.js @@ -0,0 +1,116 @@ +// 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 +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: [generators, 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)' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-before-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-before-try.js new file mode 100644 index 0000000000..743e7674da --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-before-try.js @@ -0,0 +1,56 @@ +// 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: > + When a generator is paused before a `try..catch` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + unreachable += 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; +} +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js new file mode 100644 index 0000000000..eb28117fbc --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js @@ -0,0 +1,66 @@ +// 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: > + When a generator is paused after a `try..catch` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +features: [generators] +---*/ + +var obj = {}; +var unreachable = 0; + +function* g() { + yield 1; + try { + yield 2; + throw obj; + } catch (e) { + yield e; + } + yield 3; + unreachable += 1; +} +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'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, obj, '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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js new file mode 100644 index 0000000000..5e862585e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js @@ -0,0 +1,63 @@ +// 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: > + When a generator is paused within the `catch` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + unreachable += 1; + } + yield 3; +} +var iter, result, exception; + +exception = new Test262Error(); +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, exception, '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`)' +); + +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-try.js new file mode 100644 index 0000000000..b945ef4893 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-catch-within-try.js @@ -0,0 +1,66 @@ +// 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: > + When a generator is paused within the `try` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; +function* g() { + yield 1; + try { + yield 2; + unreachable += 1; + } catch (e) { + yield e; + } + yield 3; +} +var iter, result, exception; + +exception = new Test262Error(); +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-before-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-before-try.js new file mode 100644 index 0000000000..108e7df752 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-before-try.js @@ -0,0 +1,58 @@ +// 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: > + When a generator is paused before a `try..finally` statement, `throw` + should interrupt control flow as if a `throw` statement had appeared at + that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + unreachable += 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; +} +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js new file mode 100644 index 0000000000..0ef6f1a91b --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js @@ -0,0 +1,64 @@ +// 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: > + When a generator is paused after a `try..finally` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; + unreachable += 1; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +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, '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`)' +); + +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js new file mode 100644 index 0000000000..d091c927f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js @@ -0,0 +1,72 @@ +// 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: > + When a generator is paused within a `catch` block that is declared within a + `try` block of a `try..catch` statement, `throw` should interrupt control + flow as if a `throw` statement had appeared at that location in the + function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + try { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + unreachable += 1; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var exception = new Error(); +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.throw(new Test262Error()); +assert.sameValue(result.value, 4, 'Fourth result `value`'); +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js new file mode 100644 index 0000000000..caca477bd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js @@ -0,0 +1,63 @@ +// 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: > + When a generator is paused within a `finally` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + try { + yield 1; + throw new Error(); + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + unreachable += 1; + } + unreachable += 1; + yield 5; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 4, 'Second result `value`'); +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js new file mode 100644 index 0000000000..e9ed6d31a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js @@ -0,0 +1,74 @@ +// 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: > + When a generator is paused within a `try` block that is declared within a + `try` block of a `try..catch` statement, `throw` should interrupt control + flow as if a `throw` statement had appeared at that location in the + function body. +features: [generators] +---*/ + +var unreachable = 0; +function* g() { + try { + yield 1; + try { + yield 2; + unreachable += 1; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var iter = g(); +var exception = new Error(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result value'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +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'); + +result = iter.next(); +assert.sameValue(result.value, 4, 'Fifth result `value`'); +assert.sameValue(result.done, false, 'Fifth result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 5, 'Sixth result `value`'); +assert.sameValue(result.done, false, 'Sixth result `done` flag'); + +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js new file mode 100644 index 0000000000..5427e443d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js @@ -0,0 +1,76 @@ +// 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: > + When a generator is paused within a `try` block of a `try..catch` statement + and following a nested `try..catch` statment, `throw` should interrupt + control flow as if a `throw` statement had appeared at that location in the + function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + try { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + } + yield 3; + unreachable += 1; + } finally { + yield 4; + } + yield 5; +} +var exception = new Error(); +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +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'); + +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(); +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js new file mode 100644 index 0000000000..9bb560cdd2 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js @@ -0,0 +1,62 @@ +// 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: > + When a generator is paused within a `try` block of a `try..catch` statement + and before a nested `try..catch` statement, `throw` should interrupt + control flow as if a `throw` statement had appeared at that location in the + function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + try { + yield 1; + unreachable += 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +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(); +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js new file mode 100644 index 0000000000..88d1f310e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js @@ -0,0 +1,60 @@ +// 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: > + When a generator is paused within the `finally` block of a `try..finally` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + unreachable += 1; + } + yield 4; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +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`)' +); + +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(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-try.js b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-try.js new file mode 100644 index 0000000000..aeae83a585 --- /dev/null +++ b/js/src/tests/test262/built-ins/GeneratorPrototype/throw/try-finally-within-try.js @@ -0,0 +1,60 @@ +// 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: > + When a generator is paused within a `try` block of a `try..finally` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +features: [generators] +---*/ + +var unreachable = 0; + +function* g() { + yield 1; + try { + yield 2; + unreachable += 1; + } finally { + yield 3; + } + yield 4; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.throw(new Test262Error()); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +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(); + +reportCompare(0, 0); |