mirror of https://github.com/tc39/test262.git
Extend coverage for Section 25 - Generators (#700)
* Improve tests for GeneratorPrototype methods - Assert return values more consistently - Expand tests for constraints on `this` value * Add more tests for dynamic GeneratorFunctions * Add more tests for GenerationFunction.prototype * Add more tests for the GeneratorFunction object * Extend test: GeneratorFunction.prototype.prototype * Improve precision of tests for generator methods Extend existing assertions to explicitly verify that execution halts at the intended location. Correct tests which were previously asserting this behavior in contexts that did not match their name/description. * Remove unused variables * fixup! Improve tests for GeneratorPrototype methods * fixup! Improve tests for GeneratorPrototype methods
This commit is contained in:
parent
e290a337b8
commit
fce8b5852d
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-properties-of-the-generatorfunction-constructor
|
||||
es6id: 25.2.2
|
||||
description: Object extensibility
|
||||
info: >
|
||||
The value of the [[Extensible]] internal slot of the GeneratorFunction
|
||||
constructor is true.
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert(Object.isExtensible(GeneratorFunction));
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorfunction
|
||||
es6id: 25.2.1.1
|
||||
description: Definition of instance `length` property
|
||||
info: |
|
||||
[...]
|
||||
3. Return CreateDynamicFunction(C, NewTarget, "generator", args).
|
||||
|
||||
19.2.1.1.1 Runtime Semantics: CreateDynamicFunction
|
||||
|
||||
[...]
|
||||
26. Perform FunctionInitialize(F, Normal, parameters, body, scope).
|
||||
[...]
|
||||
|
||||
9.2.4 FunctionInitialize
|
||||
|
||||
[...]
|
||||
3. Perform ! DefinePropertyOrThrow(F, "length",
|
||||
PropertyDescriptor{[[Value]]: len, [[Writable]]: false, [[Enumerable]]:
|
||||
false, [[Configurable]]: true}).
|
||||
[...]
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert.sameValue(GeneratorFunction().length, 0);
|
||||
assert.sameValue(GeneratorFunction('').length, 0);
|
||||
assert.sameValue(GeneratorFunction('x').length, 0);
|
||||
assert.sameValue(GeneratorFunction('x', '').length, 1);
|
||||
assert.sameValue(GeneratorFunction('x', 'y', '').length, 2);
|
||||
assert.sameValue(GeneratorFunction('x, y', '').length, 2);
|
||||
|
||||
verifyNotEnumerable(GeneratorFunction(), 'length');
|
||||
verifyNotWritable(GeneratorFunction(), 'length');
|
||||
verifyConfigurable(GeneratorFunction(), 'length');
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorfunction
|
||||
es6id: 25.2.1.1
|
||||
description: Definition of instance `prototype` property
|
||||
info: |
|
||||
[...]
|
||||
3. Return CreateDynamicFunction(C, NewTarget, "generator", args).
|
||||
|
||||
19.2.1.1.1 Runtime Semantics: CreateDynamicFunction
|
||||
|
||||
[...]
|
||||
27. If kind is "generator", then
|
||||
a. Let prototype be ObjectCreate(%GeneratorPrototype%).
|
||||
b. Perform DefinePropertyOrThrow(F, "prototype",
|
||||
PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true,
|
||||
[[Enumerable]]: false, [[Configurable]]: false}).
|
||||
[...]
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
var instance = GeneratorFunction();
|
||||
|
||||
assert.sameValue(typeof instance.prototype, 'object');
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(instance.prototype),
|
||||
Object.getPrototypeOf(instance).prototype
|
||||
);
|
||||
|
||||
verifyNotEnumerable(instance, 'prototype');
|
||||
verifyWritable(instance, 'prototype');
|
||||
verifyNotConfigurable(instance, 'prototype');
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorfunction
|
||||
es6id: 25.2.1.1
|
||||
description: Definition of instance `length` property
|
||||
info: |
|
||||
[...]
|
||||
3. Return CreateDynamicFunction(C, NewTarget, "generator", args).
|
||||
|
||||
19.2.1.1.1 Runtime Semantics: CreateDynamicFunction
|
||||
|
||||
[...]
|
||||
20. If kind is "generator", then
|
||||
a. If parameters Contains YieldExpression is true, throw a SyntaxError
|
||||
exception.
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
// YieldExpression is permitted in function body.
|
||||
GeneratorFunction('x = yield');
|
||||
|
||||
assert.throws(SyntaxError, function() {
|
||||
GeneratorFunction('x = yield', '');
|
||||
}, 'YieldExpression not permitted generally');
|
||||
|
||||
var withinGenerator = function*() {
|
||||
GeneratorFunction('x = yield', '');
|
||||
};
|
||||
|
||||
assert.throws(SyntaxError, function() {
|
||||
withinGenerator().next();
|
||||
}, 'YieldExpression not permitted when calling context is a generator');
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorfunction.length
|
||||
es6id: 25.2.2.1
|
||||
description: >
|
||||
This is a data property with a value of 1. This property has the attributes {
|
||||
[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert.sameValue(GeneratorFunction.length, 1);
|
||||
|
||||
verifyNotEnumerable(GeneratorFunction, 'length');
|
||||
verifyNotWritable(GeneratorFunction, 'length');
|
||||
verifyConfigurable(GeneratorFunction, 'length');
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-properties-of-the-generatorfunction-constructor
|
||||
es6id: 25.2.2
|
||||
description: Function "name" property
|
||||
info: >
|
||||
The value of the name property of the GeneratorFunction is
|
||||
"GeneratorFunction".
|
||||
|
||||
17 ECMAScript Standard Built-in Objects:
|
||||
Every built-in Function object, including constructors, that is not
|
||||
identified as an anonymous function has a name property whose value is a
|
||||
String.
|
||||
|
||||
Unless otherwise specified, the name property of a built-in Function object,
|
||||
if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]:
|
||||
false, [[Configurable]]: true }.
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert.sameValue(GeneratorFunction.name, 'GeneratorFunction');
|
||||
|
||||
verifyNotEnumerable(GeneratorFunction, 'name');
|
||||
verifyNotWritable(GeneratorFunction, 'name');
|
||||
verifyConfigurable(GeneratorFunction, 'name');
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorfunction.prototype.constructor
|
||||
es6id: 25.2.3.1
|
||||
description: >
|
||||
`constructor` property of the GeneratorFunction.prototype object
|
||||
info: >
|
||||
The initial value of GeneratorFunction.prototype.constructor is the intrinsic
|
||||
object %GeneratorFunction%.
|
||||
|
||||
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
|
||||
false, [[Configurable]]: true }.
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert.sameValue(GeneratorFunction.prototype.constructor, GeneratorFunction);
|
||||
|
||||
verifyNotEnumerable(GeneratorFunction.prototype, 'constructor');
|
||||
verifyNotWritable(GeneratorFunction.prototype, 'constructor');
|
||||
verifyConfigurable(GeneratorFunction.prototype, 'constructor');
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-properties-of-the-generatorfunction-prototype-object
|
||||
es6id: 25.2.3
|
||||
description: Object extensibility
|
||||
info: >
|
||||
The initial value of the [[Extensible]] internal slot of the
|
||||
GeneratorFunction prototype object is true.
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
assert(Object.isExtensible(GeneratorFunction.prototype));
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 25.4.5.1
|
||||
description: GeneratorFunction.prototype property descriptor
|
||||
info: >
|
||||
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
|
||||
false, [[Configurable]]: false }.
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
|
||||
|
||||
verifyNotEnumerable(GeneratorFunction, 'prototype');
|
||||
verifyNotWritable(GeneratorFunction, 'prototype');
|
||||
verifyNotConfigurable(GeneratorFunction, 'prototype');
|
|
@ -5,9 +5,18 @@ es6id: 25.2.3.2
|
|||
description: >
|
||||
The value of GeneratorFunction.prototype.prototype is the
|
||||
%GeneratorPrototype% intrinsic object.
|
||||
|
||||
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
|
||||
false, [[Configurable]]: true }.
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
var GeneratorFunctionPrototype = Object.getPrototypeOf(function*() {});
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(function*() {}).prototype,
|
||||
GeneratorFunctionPrototype.prototype,
|
||||
Object.getPrototypeOf(function*() {}.prototype)
|
||||
);
|
||||
|
||||
verifyNotEnumerable(GeneratorFunctionPrototype, 'prototype');
|
||||
verifyNotWritable(GeneratorFunctionPrototype, 'prototype');
|
||||
verifyConfigurable(GeneratorFunctionPrototype, 'prototype');
|
||||
|
|
|
@ -1,12 +1,41 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorvalidate
|
||||
es6id: 25.3.3.2
|
||||
description: >
|
||||
A TypeError should be thrown if the generator is resumed while running.
|
||||
A TypeError should be thrown if the generator is resumed while in the
|
||||
"executing" state and the generator should be marked as "completed"
|
||||
info: |
|
||||
25.3.3.1 GeneratorStart
|
||||
|
||||
[...]
|
||||
4. Set the code evaluation state of genContext such that when evaluation is
|
||||
resumed for that execution context the following steps will be performed:
|
||||
a. Let result be the result of evaluating generatorBody.
|
||||
b. Assert: If we return here, the generator either threw an exception or
|
||||
performed either an implicit or explicit return.
|
||||
c. Remove genContext from the execution context stack and restore the
|
||||
execution context that is at the top of the execution context stack as
|
||||
the running execution context.
|
||||
d. Set generator.[[GeneratorState]] to "completed".
|
||||
[...]
|
||||
|
||||
25.3.3.3 GeneratorResume
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
3. Assert: generator also has a [[GeneratorContext]] internal slot.
|
||||
4. Let state be generator.[[GeneratorState]].
|
||||
5. If state is "executing", throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
var iter;
|
||||
var iter, result;
|
||||
function* withoutVal() {
|
||||
iter.next();
|
||||
}
|
||||
|
@ -17,9 +46,33 @@ function* withVal() {
|
|||
iter = withoutVal();
|
||||
assert.throws(TypeError, function() {
|
||||
iter.next();
|
||||
});
|
||||
}, 'Error when invoked without value');
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(
|
||||
typeof result, 'object', 'type following invocation without value'
|
||||
);
|
||||
assert.sameValue(
|
||||
result.value, undefined, '`value` following invocation without value'
|
||||
);
|
||||
assert.sameValue(
|
||||
result.done, true, '`done` following invocation without value'
|
||||
);
|
||||
|
||||
iter = withVal();
|
||||
assert.throws(TypeError, function() {
|
||||
iter.next();
|
||||
});
|
||||
}, 'Error when invoked with value');
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(
|
||||
typeof result, 'object', 'type following invocation with value'
|
||||
);
|
||||
assert.sameValue(
|
||||
result.value, undefined, '`value` following invocation with value'
|
||||
);
|
||||
assert.sameValue(
|
||||
result.done, true, '`done` following invocation with value'
|
||||
);
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 25.3.1.2
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `next` does not defined the [[GeneratorState]] internal slot.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(1, 1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call({}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call({}, 1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}, 1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(g); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(g, 1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype, 1); });
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.next
|
||||
es6id: 25.3.1.2
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `next` does not define the [[GeneratorState]] internal slot.
|
||||
info: |
|
||||
1. Let g be the this value.
|
||||
2. Return GeneratorResume(g, value).
|
||||
|
||||
25.3.3.3 GeneratorResume
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
[...]
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call({}); },
|
||||
'ordinary object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call({}, 1); },
|
||||
'ordinary object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(function() {}); },
|
||||
'function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(function() {}, 1); },
|
||||
'function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(g); },
|
||||
'generator function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(g, 1); },
|
||||
'generator function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(g.prototype); },
|
||||
'generator function prototype object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(g.prototype, 1); },
|
||||
'generator function prototype object (with value)'
|
||||
);
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.next
|
||||
es6id: 25.3.1.2
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this"
|
||||
value of `next` is not an object.
|
||||
info: |
|
||||
1. Let g be the this value.
|
||||
2. Return GeneratorResume(g, value).
|
||||
|
||||
25.3.3.3 GeneratorResume
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
var symbol = Symbol();
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(undefined); },
|
||||
'undefined (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(undefined, 1); },
|
||||
'undefined (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(null); },
|
||||
'null (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(null, 1); },
|
||||
'null (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(true); },
|
||||
'boolean (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(true, 1); },
|
||||
'boolean (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call('s'); },
|
||||
'string (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call('s', 1); },
|
||||
'string (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(1); },
|
||||
'number (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(1, 1); },
|
||||
'number (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(symbol); },
|
||||
'symbol (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.next.call(symbol, 1); },
|
||||
'symbol (with value)'
|
||||
);
|
|
@ -13,9 +13,12 @@ var iter, result;
|
|||
iter = G();
|
||||
iter.next();
|
||||
|
||||
iter.return(33);
|
||||
result = iter.return(33);
|
||||
|
||||
assert.sameValue(result.value, 33, 'return: result `value`');
|
||||
assert.sameValue(result.done, true, 'return: result `done` flag');
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(result.value, undefined, 'Result `value`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag');
|
||||
assert.sameValue(result.value, undefined, 'next: result `value`');
|
||||
assert.sameValue(result.done, true, 'next: result `done` flag');
|
||||
|
|
|
@ -1,13 +1,41 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorvalidate
|
||||
es6id: 25.3.3.2
|
||||
description: >
|
||||
A TypeError should be thrown if the generator is resumed abruptly while
|
||||
running.
|
||||
A TypeError should be thrown if the generator is in the "executing" state,
|
||||
and the generator should be marked as "completed"
|
||||
info: |
|
||||
25.3.3.1 GeneratorStart
|
||||
|
||||
[...]
|
||||
4. Set the code evaluation state of genContext such that when evaluation is
|
||||
resumed for that execution context the following steps will be performed:
|
||||
a. Let result be the result of evaluating generatorBody.
|
||||
b. Assert: If we return here, the generator either threw an exception or
|
||||
performed either an implicit or explicit return.
|
||||
c. Remove genContext from the execution context stack and restore the
|
||||
execution context that is at the top of the execution context stack as
|
||||
the running execution context.
|
||||
d. Set generator.[[GeneratorState]] to "completed".
|
||||
[...]
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
3. Assert: generator also has a [[GeneratorContext]] internal slot.
|
||||
4. Let state be generator.[[GeneratorState]].
|
||||
5. If state is "executing", throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
var iter;
|
||||
var iter, result;
|
||||
function* g() {
|
||||
iter.return(42);
|
||||
}
|
||||
|
@ -16,3 +44,9 @@ iter = g();
|
|||
assert.throws(TypeError, function() {
|
||||
iter.next();
|
||||
});
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(typeof result, 'object');
|
||||
assert.sameValue(result.value, undefined);
|
||||
assert.sameValue(result.done, true);
|
||||
|
|
|
@ -8,8 +8,9 @@ description: >
|
|||
state.
|
||||
---*/
|
||||
|
||||
var bodyCount = 0;
|
||||
function* G() {
|
||||
yield 1;
|
||||
bodyCount += 1;
|
||||
}
|
||||
var iter = G();
|
||||
var result;
|
||||
|
@ -18,8 +19,14 @@ result = iter.return(56);
|
|||
|
||||
assert.sameValue(result.value, 56);
|
||||
assert.sameValue(result.done, true);
|
||||
assert.sameValue(
|
||||
bodyCount, 0, 'body not evaluated during processing of `return` method'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(result.value, undefined, 'Result `value`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag');
|
||||
assert.sameValue(
|
||||
bodyCount, 0, 'body not evaluated when "completed" generator is advanced'
|
||||
);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 25.3.1.3
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `return` does not defined the [[GeneratorState]] internal slot.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.return.call(1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.return.call({}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.return.call(function() {}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.return.call(g); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.return.call(g.prototype); });
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.return
|
||||
es6id: 25.3.1.3
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `return` does not define the [[GeneratorState]] internal slot.
|
||||
info: |
|
||||
[...]
|
||||
3. Return ? GeneratorResumeAbrupt(g, C).
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
[...]
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call({}); },
|
||||
'ordinary object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call({}, 1); },
|
||||
'ordinary object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(function() {}); },
|
||||
'function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(function() {}, 1); },
|
||||
'function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(g); },
|
||||
'generator function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(g, 1); },
|
||||
'generator function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(g.prototype); },
|
||||
'generator function prototype object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(g.prototype, 1); },
|
||||
'generator function prototype object (with value)'
|
||||
);
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.return
|
||||
es6id: 25.3.1.3
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this"
|
||||
value of `return` is not an object.
|
||||
info: |
|
||||
[...]
|
||||
3. Return ? GeneratorResumeAbrupt(g, C).
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
var symbol = Symbol();
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(undefined); },
|
||||
'undefined (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(undefined, 1); },
|
||||
'undefined (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(null); },
|
||||
'null (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(null, 1); },
|
||||
'null (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(true); },
|
||||
'boolean (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(true, 1); },
|
||||
'boolean (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call('s'); },
|
||||
'string (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call('s', 1); },
|
||||
'string (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(1); },
|
||||
'number (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(1, 1); },
|
||||
'number (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(symbol); },
|
||||
'symbol (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.return.call(symbol, 1); },
|
||||
'symbol (with value)'
|
||||
);
|
|
@ -8,24 +8,34 @@ description: >
|
|||
location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield;
|
||||
try {
|
||||
$ERROR('This code is unreachable (within `try` block)');
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (paused at yield)'
|
||||
);
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value,
|
||||
undefined, 'Result `value` is undefined when complete'
|
||||
|
@ -33,3 +43,6 @@ assert.sameValue(result.value,
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,27 +8,36 @@ description: >
|
|||
location in the function body.
|
||||
---*/
|
||||
|
||||
var afterCatch = false;
|
||||
var afterCatch = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {}
|
||||
afterCatch = true;
|
||||
afterCatch += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(afterCatch, true);
|
||||
assert.sameValue(afterCatch, 1);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (paused at yield)'
|
||||
);
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(
|
||||
result.value, 45, 'Result `value` following `return`'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -37,3 +46,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,29 +8,35 @@ description: >
|
|||
statement had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var inCatch = false;
|
||||
var inCatch = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
inCatch = true;
|
||||
inCatch += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `catch` block)');
|
||||
unreachable += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(inCatch, true);
|
||||
assert.sameValue(inCatch, 1);
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(
|
||||
result.value, 45, 'Result `value` following `return`'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -39,3 +45,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,27 +8,33 @@ description: >
|
|||
statement had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var inTry = false;
|
||||
var inTry = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
inTry = true;
|
||||
inTry += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `try` block)');
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(inTry, true);
|
||||
assert.sameValue(inTry, 1);
|
||||
|
||||
result = iter.return(44);
|
||||
assert.sameValue(result.value, 44, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -37,3 +43,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,23 +8,32 @@ description: >
|
|||
that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield;
|
||||
unreachable += 1;
|
||||
try {
|
||||
$ERROR('This code is unreachable (within `try` block)');
|
||||
} finally {
|
||||
$ERROR('This code is unreachable (within `finally` block)');
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (paused at yield)'
|
||||
);
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -33,3 +42,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,26 +8,37 @@ description: >
|
|||
that location in the function body.
|
||||
---*/
|
||||
|
||||
var afterFinally = false;
|
||||
var afterFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
} finally {}
|
||||
afterFinally = true;
|
||||
afterFinally += 1;
|
||||
yield;
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(afterFinally, true);
|
||||
assert.sameValue(afterFinally, 1);
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -9,35 +9,41 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var inCatch = false;
|
||||
var inFinally = false;
|
||||
var inCatch = 0;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
inCatch = true;
|
||||
inCatch += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `catch` block)');
|
||||
unreachable += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following nested `try` statement)');
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following outer `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(inCatch, true, '`catch` code patch executed');
|
||||
assert.sameValue(inFinally, false, '`finally` code path not executed');
|
||||
assert.sameValue(inCatch, 1, '`catch` code patch executed');
|
||||
assert.sameValue(inFinally, 0, '`finally` code path not executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -46,3 +52,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when compelete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,30 +8,37 @@ description: >
|
|||
statement had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var inFinally = false;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
throw new Error();
|
||||
try {
|
||||
} catch (e) {}
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `finally` block)');
|
||||
unreachable += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following outer `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when complete'
|
||||
|
@ -39,3 +46,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -9,37 +9,43 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var inTry = false;
|
||||
var inFinally = false;
|
||||
var inTry = 0;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
try {
|
||||
inTry = true;
|
||||
inTry += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within nested `try` block)');
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
$ERROR('This code is unreachable (following nested `try` statement)');
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following outer `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var exception = new Error();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(inTry, true, 'Nested `try` code patch executed');
|
||||
assert.sameValue(inFinally, false, '`finally` code path not executed');
|
||||
assert.sameValue(inTry, 1, 'Nested `try` code patch executed');
|
||||
assert.sameValue(inFinally, 0, '`finally` code path not executed');
|
||||
|
||||
result = iter.return(45);
|
||||
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -48,3 +54,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -9,33 +9,40 @@ description: >
|
|||
the function body.
|
||||
---*/
|
||||
|
||||
var inCatch = false;
|
||||
var inFinally = false;
|
||||
var inCatch = 0;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
inCatch = true;
|
||||
inCatch += 1;
|
||||
}
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
}
|
||||
yield;
|
||||
$ERROR('This code is unreachable');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(inCatch, true, '`catch` code path executed');
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inCatch, 1, '`catch` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when complete'
|
||||
|
@ -43,3 +50,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -9,35 +9,42 @@ description: >
|
|||
the function body.
|
||||
---*/
|
||||
|
||||
var inTry = false;
|
||||
var inFinally = false;
|
||||
var inTry = 0;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
inTry = true;
|
||||
inTry += 1;
|
||||
yield;
|
||||
try {
|
||||
$ERROR('This code is unreachable (within nested `try` block)');
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
$ERROR('This code is unreacahable (following nested `try` statement)');
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
}
|
||||
$ERROR('This codeis unreachable (following outer `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(inTry, true, '`try` code path executed');
|
||||
assert.sameValue(inFinally, false, '`finally` code path not executed');
|
||||
assert.sameValue(inTry, 1, '`try` code path executed');
|
||||
assert.sameValue(inFinally, 0, '`finally` code path not executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Second result `value`');
|
||||
assert.sameValue(result.done, true, 'Second result `done` flag');
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -46,3 +53,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,27 +8,34 @@ description: >
|
|||
statement had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var inFinally = true;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `finally` block)');
|
||||
unreachable += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when complete'
|
||||
|
@ -36,3 +43,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -8,30 +8,37 @@ description: >
|
|||
statement had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var inTry = false;
|
||||
var inFinally = false;
|
||||
var inTry = 0;
|
||||
var inFinally = 0;
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
inTry = true;
|
||||
inTry += 1;
|
||||
yield;
|
||||
$ERROR('This code is unreachable (within `try` block)');
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
inFinally = true;
|
||||
inFinally += 1;
|
||||
}
|
||||
$ERROR('This code is unreachable (following `try` statement)');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
||||
iter.next();
|
||||
|
||||
assert.sameValue(inTry, true, '`try` block code path executed');
|
||||
assert.sameValue(inFinally, false, '`finally` code path not executed');
|
||||
assert.sameValue(inTry, 1, '`try` block code path executed');
|
||||
assert.sameValue(inFinally, 0, '`finally` code path not executed');
|
||||
|
||||
result = iter.return(45);
|
||||
assert.sameValue(result.value, 45, 'Result `value` following `return`');
|
||||
assert.sameValue(result.done, true, 'Result `done` flag following `return`');
|
||||
assert.sameValue(inFinally, true, '`finally` code path executed');
|
||||
assert.sameValue(inFinally, 1, '`finally` code path executed');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `return`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
|
@ -40,3 +47,6 @@ assert.sameValue(
|
|||
assert.sameValue(
|
||||
result.done, true, 'Result `done` flag is `true` when complete'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
|
|
@ -1,13 +1,41 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generatorvalidate
|
||||
es6id: 25.3.3.2
|
||||
description: >
|
||||
A TypeError should be thrown if the generator is resumed abruptly while
|
||||
running.
|
||||
A TypeError should be thrown if the generator is in the "executing" state,
|
||||
and the generator should be marked as "completed"
|
||||
info: |
|
||||
25.3.3.1 GeneratorStart
|
||||
|
||||
[...]
|
||||
4. Set the code evaluation state of genContext such that when evaluation is
|
||||
resumed for that execution context the following steps will be performed:
|
||||
a. Let result be the result of evaluating generatorBody.
|
||||
b. Assert: If we return here, the generator either threw an exception or
|
||||
performed either an implicit or explicit return.
|
||||
c. Remove genContext from the execution context stack and restore the
|
||||
execution context that is at the top of the execution context stack as
|
||||
the running execution context.
|
||||
d. Set generator.[[GeneratorState]] to "completed".
|
||||
[...]
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
3. Assert: generator also has a [[GeneratorContext]] internal slot.
|
||||
4. Let state be generator.[[GeneratorState]].
|
||||
5. If state is "executing", throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
var iter;
|
||||
var iter, result;
|
||||
function* g() {
|
||||
iter.throw(42);
|
||||
}
|
||||
|
@ -16,3 +44,9 @@ iter = g();
|
|||
assert.throws(TypeError, function() {
|
||||
iter.next();
|
||||
});
|
||||
|
||||
result = iter.next();
|
||||
|
||||
assert.sameValue(typeof result, 'object');
|
||||
assert.sameValue(result.value, undefined);
|
||||
assert.sameValue(result.done, true);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
es6id: 25.3.1.4
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `throw` does not defined the [[GeneratorState]] internal slot.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.throw.call(1); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.throw.call({}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.throw.call(function() {}); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g); });
|
||||
assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g.prototype); });
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.throw
|
||||
es6id: 25.3.1.4
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the
|
||||
context of `throw` does not define the [[GeneratorState]] internal slot.
|
||||
info: |
|
||||
[...]
|
||||
3. Return ? GeneratorResumeAbrupt(g, C).
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
[...]
|
||||
2. If generator does not have a [[GeneratorState]] internal slot, throw a
|
||||
TypeError exception.
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call({}); },
|
||||
'ordinary object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call({}, 1); },
|
||||
'ordinary object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(function() {}); },
|
||||
'function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(function() {}, 1); },
|
||||
'function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(g); },
|
||||
'generator function object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(g, 1); },
|
||||
'generator function object (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(g.prototype); },
|
||||
'generator function prototype object (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(g.prototype, 1); },
|
||||
'generator function prototype object (with value)'
|
||||
);
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (C) 2013 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-generator.prototype.throw
|
||||
es6id: 25.3.1.4
|
||||
description: >
|
||||
A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the "this"
|
||||
value of `throw` is not an object.
|
||||
info: |
|
||||
[...]
|
||||
3. Return ? GeneratorResumeAbrupt(g, C).
|
||||
|
||||
25.3.3.4 GeneratorResumeAbrupt
|
||||
|
||||
1. Let state be ? GeneratorValidate(generator).
|
||||
|
||||
25.3.3.2 GeneratorValidate
|
||||
|
||||
1. If Type(generator) is not Object, throw a TypeError exception.
|
||||
features: [Symbol]
|
||||
---*/
|
||||
|
||||
function* g() {}
|
||||
var GeneratorPrototype = Object.getPrototypeOf(g).prototype;
|
||||
var symbol = Symbol();
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(undefined); },
|
||||
'undefined (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(undefined, 1); },
|
||||
'undefined (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(null); },
|
||||
'null (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(null, 1); },
|
||||
'null (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(true); },
|
||||
'boolean (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(true, 1); },
|
||||
'boolean (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call('s'); },
|
||||
'string (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call('s', 1); },
|
||||
'string (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(1); },
|
||||
'number (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(1, 1); },
|
||||
'number (with value)'
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(symbol); },
|
||||
'symbol (without value)'
|
||||
);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function() { GeneratorPrototype.throw.call(symbol, 1); },
|
||||
'symbol (with value)'
|
||||
);
|
|
@ -8,8 +8,10 @@ description: >
|
|||
location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
unreachable += 1;
|
||||
try {
|
||||
yield 2;
|
||||
} catch (e) {
|
||||
|
@ -17,19 +19,32 @@ function* g() {
|
|||
}
|
||||
yield 3;
|
||||
}
|
||||
var iter, result, exception;
|
||||
var iter, result;
|
||||
|
||||
iter = g();
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value, 1, 'First result `value`');
|
||||
assert.sameValue(result.done, false, 'First result `done` flag');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (paused at yield)'
|
||||
);
|
||||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value,
|
||||
undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -9,6 +9,7 @@ description: >
|
|||
---*/
|
||||
|
||||
var obj = {};
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
|
@ -18,6 +19,7 @@ function* g() {
|
|||
yield e;
|
||||
}
|
||||
yield 3;
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter, result;
|
||||
|
||||
|
@ -40,10 +42,19 @@ assert.sameValue(result.done, false, 'Fourth result `done` flag');
|
|||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,6 +8,7 @@ description: >
|
|||
had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
|
@ -15,6 +16,7 @@ function* g() {
|
|||
throw exception;
|
||||
} catch (e) {
|
||||
yield e;
|
||||
unreachable += 1;
|
||||
}
|
||||
yield 3;
|
||||
}
|
||||
|
@ -35,15 +37,21 @@ result = iter.next();
|
|||
assert.sameValue(result.value, exception, 'Third result `value`');
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value, 3, 'Fourth result `value`');
|
||||
assert.sameValue(result.done, false, 'Fourth result `done` flag');
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,10 +8,12 @@ description: >
|
|||
had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
yield 2;
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
yield e;
|
||||
}
|
||||
|
@ -34,14 +36,28 @@ result = iter.throw(exception);
|
|||
assert.sameValue(result.value, exception, 'Third result `value`');
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value, 3, 'Fourth result `done` flag');
|
||||
assert.sameValue(result.done, false, 'Fourth result `value`');
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `catch`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,8 +8,10 @@ description: >
|
|||
that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
unreachable += 1;
|
||||
try {
|
||||
yield 2;
|
||||
} finally {
|
||||
|
@ -26,13 +28,25 @@ assert.sameValue(result.value, 1, 'First result `value`');
|
|||
assert.sameValue(
|
||||
result.done, false, 'First result `done` flag'
|
||||
);
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (paused at yield)'
|
||||
);
|
||||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue( result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,6 +8,7 @@ description: >
|
|||
location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
|
@ -16,7 +17,7 @@ function* g() {
|
|||
yield 3;
|
||||
}
|
||||
yield 4;
|
||||
$ERROR('This code is unreachable');
|
||||
unreachable += 1;
|
||||
}
|
||||
var iter = g();
|
||||
var result;
|
||||
|
@ -39,10 +40,19 @@ assert.sameValue(result.done, false, 'Third result `done` flag');
|
|||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -9,6 +9,7 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
yield 1;
|
||||
|
@ -17,6 +18,7 @@ function* g() {
|
|||
throw exception;
|
||||
} catch (e) {
|
||||
yield e;
|
||||
unreachable += 1;
|
||||
}
|
||||
yield 3;
|
||||
} finally {
|
||||
|
@ -46,10 +48,19 @@ assert.sameValue(result.done, false, 'Fourth result `done` flag');
|
|||
|
||||
assert.throws(Test262Error, function() { iter.next(); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,6 +8,7 @@ description: >
|
|||
had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
yield 1;
|
||||
|
@ -20,7 +21,9 @@ function* g() {
|
|||
yield 3;
|
||||
} finally {
|
||||
yield 4;
|
||||
unreachable += 1;
|
||||
}
|
||||
unreachable += 1;
|
||||
yield 5;
|
||||
}
|
||||
var iter = g();
|
||||
|
@ -36,10 +39,19 @@ assert.sameValue(result.done, false, 'First result `done` flag');
|
|||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -9,11 +9,13 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
yield 1;
|
||||
try {
|
||||
yield 2;
|
||||
unreachable += 1;
|
||||
} catch (e) {
|
||||
yield e;
|
||||
}
|
||||
|
@ -39,6 +41,12 @@ result = iter.throw(exception);
|
|||
assert.sameValue(result.value, exception, 'Third result `value`');
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value, 3, 'Fourth result `value');
|
||||
assert.sameValue(result.done, false, 'Fourth result `done` flag');
|
||||
|
@ -56,5 +64,8 @@ assert.sameValue(
|
|||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -9,6 +9,7 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
yield 1;
|
||||
|
@ -19,6 +20,7 @@ function* g() {
|
|||
yield e;
|
||||
}
|
||||
yield 3;
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
yield 4;
|
||||
}
|
||||
|
@ -48,6 +50,12 @@ result = iter.throw(new Test262Error());
|
|||
assert.sameValue(result.value, 4, 'Fifth result `value`');
|
||||
assert.sameValue(result.done, false, 'Fifth result `done` flag');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
assert.throws(Test262Error, function() { iter.next(); });
|
||||
|
||||
result = iter.next();
|
||||
|
@ -55,5 +63,8 @@ assert.sameValue(
|
|||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -9,9 +9,11 @@ description: >
|
|||
function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
try {
|
||||
yield 1;
|
||||
unreachable += 1;
|
||||
try {
|
||||
yield 2;
|
||||
} catch (e) {
|
||||
|
@ -34,6 +36,12 @@ result = iter.throw(new Test262Error());
|
|||
assert.sameValue(result.value, 4, 'Second result `value`');
|
||||
assert.sameValue(result.done, false, 'Second result `done` flag');
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
assert.throws(Test262Error, function() { iter.next(); });
|
||||
|
||||
result = iter.next();
|
||||
|
@ -41,5 +49,8 @@ assert.sameValue(
|
|||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,12 +8,14 @@ description: >
|
|||
had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
yield 2;
|
||||
} finally {
|
||||
yield 3;
|
||||
unreachable += 1;
|
||||
}
|
||||
yield 4;
|
||||
}
|
||||
|
@ -32,16 +34,21 @@ result = iter.next();
|
|||
assert.sameValue(result.value, 3, 'Third result `value`');
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(result.value, 4, 'Fourth result `value`');
|
||||
assert.sameValue(result.done, false, 'Fourth result `done` flag');
|
||||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
|
@ -8,10 +8,12 @@ description: >
|
|||
had appeared at that location in the function body.
|
||||
---*/
|
||||
|
||||
var unreachable = 0;
|
||||
function* g() {
|
||||
yield 1;
|
||||
try {
|
||||
yield 2;
|
||||
unreachable += 1;
|
||||
} finally {
|
||||
yield 3;
|
||||
}
|
||||
|
@ -28,16 +30,25 @@ result = iter.next();
|
|||
assert.sameValue(result.value, 2, 'Second result `value`');
|
||||
assert.sameValue(result.done, false, 'Second result `done` flag');
|
||||
|
||||
result = iter.next();
|
||||
result = iter.throw(new Test262Error());
|
||||
assert.sameValue(result.value, 3, 'Third result `value`');
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
|
||||
assert.throws(Test262Error, function() { iter.throw(new Test262Error()); });
|
||||
assert.sameValue(
|
||||
unreachable,
|
||||
0,
|
||||
'statement following `yield` not executed (following `throw`)'
|
||||
);
|
||||
|
||||
assert.throws(Test262Error, function() { iter.next(); });
|
||||
|
||||
result = iter.next();
|
||||
assert.sameValue(
|
||||
result.value, undefined, 'Result `value` is undefined when done'
|
||||
);
|
||||
assert.sameValue(result.done, true, 'Result `done` flag is `true` when done');
|
||||
assert.sameValue(
|
||||
unreachable, 0, 'statement following `yield` not executed (once "completed")'
|
||||
);
|
||||
|
||||
iter.next();
|
||||
|
|
Loading…
Reference in New Issue