Improve coverage for YieldExpression (#681)

* Re-organize coverage for YieldExpression

* Extend test coverge for YieldExpression

* fixup! Extend test coverge for YieldExpression

Remove unused variables
This commit is contained in:
jugglinmike 2016-10-24 14:29:56 -04:00 committed by Tom Care
parent 720c3cc8cc
commit c9569a7e7e
49 changed files with 2346 additions and 240 deletions

View File

@ -1,115 +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.
/*---
description: >
`yield` is a valid expression within generator function bodies.
es6id: 14.4
---*/
var result, iter;
var g1 = function*() { (yield 1) };
var g2 = function*() { [yield 1] };
var g3 = function*() { {yield 1} };
var g4 = function*() { yield 1, yield 2; };
var g5 = function*() { (yield 1) ? yield 2 : yield 3; };
iter = g1();
result = iter.next();
assert.sameValue(result.value, 1, 'Within grouping operator: result `value`');
assert.sameValue(
result.done, false, 'Within grouping operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following grouping operator: result `value`'
);
assert.sameValue(
result.done, true, 'Following grouping operator: result `done` flag'
);
iter = g2();
result = iter.next();
assert.sameValue(result.value, 1, 'Within array literal: result `value`');
assert.sameValue(
result.done, false, 'Within array literal: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following array literal: result `value`'
);
assert.sameValue(
result.done, true, 'Following array literal: result `done` flag'
);
iter = g3();
result = iter.next();
assert.sameValue(result.value, 1, 'Within object literal: result `value`');
assert.sameValue(
result.done, false, 'Within object literal: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following object literal: result `value`'
);
assert.sameValue(
result.done, true, 'Following object literal: result `done` flag'
);
iter = g4();
result = iter.next();
assert.sameValue(
result.value, 1, 'First expression in comma expression: result `value`'
);
assert.sameValue(
result.done,
false,
'First expression in comma expression: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, 2, 'Second expression in comma expression: result `value`'
);
assert.sameValue(
result.done,
false,
'Second expression in comma expression: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following comma expression: result `value`'
);
assert.sameValue(
result.done, true, 'Following comma expression: result `done` flag'
);
iter = g5();
result = iter.next();
assert.sameValue(
result.value,
1,
'Conditional expression in conditional operator: result `value`'
);
assert.sameValue(
result.done,
false,
'Conditional expression in conditional operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value,
3,
'Branch in conditional operator: result `value`'
);
assert.sameValue(
result.done,
false,
'Branch in conditional operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following conditional operator: result `value`'
);
assert.sameValue(
result.done, true, 'Following conditional operator: result `done` flag'
);

View File

@ -1,125 +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.
/*---
description: >
`yield` is a valid expression within generator function bodies.
es6id: 14.4
---*/
var iter, result;
var g1 = function*() { (yield) };
var g2 = function*() { [yield] };
var g3 = function*() { {yield} };
var g4 = function*() { yield, yield; };
var g5 = function*() { (yield) ? yield : yield; };
iter = g1();
result = iter.next();
assert.sameValue(
result.value, undefined, 'Within grouping operator: result `value`'
);
assert.sameValue(
result.done, false, 'Within grouping operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following grouping operator: result `value`'
);
assert.sameValue(
result.done, true, 'Following grouping operator: result `done` flag'
);
iter = g2();
result = iter.next();
assert.sameValue(
result.value, undefined, 'Within array literal: result `value`'
);
assert.sameValue(
result.done, false, 'Within array literal: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following array literal: result `value`'
);
assert.sameValue(
result.done, true, 'Following array literal: result `done` flag'
);
iter = g3();
result = iter.next();
assert.sameValue(
result.value, undefined, 'Within object literal: result `value`'
);
assert.sameValue(
result.done, false, 'Within object literal: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following object literal: result `value`'
);
assert.sameValue(
result.done, true, 'Following object literal: result `done` flag'
);
iter = g4();
result = iter.next();
assert.sameValue(
result.value,
undefined,
'First expression in comma expression: result `value`'
);
assert.sameValue(
result.done,
false,
'First expression in comma expression: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value,
undefined,
'Second expression in comma expression: result `value`'
);
assert.sameValue(
result.done,
false,
'Second expression in comma expression: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following comma expression: result `value`'
);
assert.sameValue(
result.done, true, 'Following comma expression: result `done` flag'
);
iter = g5();
result = iter.next();
assert.sameValue(
result.value,
undefined,
'Conditional expression in conditional operator: result `value`'
);
assert.sameValue(
result.done,
false,
'Conditional expression in conditional operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value,
undefined,
'Branch in conditional operator: result `value`'
);
assert.sameValue(
result.done,
false,
'Branch in conditional operator: result `done` flag'
);
result = iter.next();
assert.sameValue(
result.value, undefined, 'Following conditional operator: result `value`'
);
assert.sameValue(
result.done, true, 'Following conditional operator: result `done` flag'
);

View File

@ -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-generator-function-definitions
es6id: 14.4
description: >
YieldExpression operand may not include the `in` keyword in contexts where it
is disallowed
info: |
Syntax
yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
negative: SyntaxError
---*/
function* g() {
for (yield '' in {}; ; ) ;
}

View File

@ -0,0 +1,47 @@
// 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-generator-function-definitions
es6id: 14.4
description: >
YieldExpression contextually recognizes the `in` keyword as part of a
RelationalExpression
info: |
Syntax
yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
---*/
var obj = Object.create(null);
var iter, iterResult, value;
function* g() {
value = yield 'hit' in obj;
value = yield 'miss' in obj;
}
obj.hit = true;
iter = g();
iterResult = iter.next('first');
assert.sameValue(iterResult.done, false, '`done` property (first iteration)');
assert.sameValue(iterResult.value, true, '`value` property (first iteration)');
assert.sameValue(
value, undefined, 'generator paused prior to evaluating AssignmentExpression'
);
iterResult = iter.next('second');
assert.sameValue(iterResult.done, false, '`done` property (second iteration)');
assert.sameValue(
iterResult.value, false, '`value` property (second iteration)'
);
assert.sameValue(value, 'second', 'value of first AssignmentExpression');
iterResult = iter.next('third');
assert.sameValue(iterResult.done, true, '`done` property (third iteration)');
assert.sameValue(
iterResult.value, undefined, '`value` property (third iteration)'
);
assert.sameValue(value, 'third', 'value of second AssignmentExpression');

View File

@ -0,0 +1,39 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Iteration protocol is not initiated for non-delegating YieldExpression
info: |
YieldExpression:yieldAssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Return ? GeneratorYield(CreateIterResultObject(value, false)).
features: [Symbol.iterator]
---*/
var callCount = 0;
var iterSpy = Object.defineProperty({}, Symbol.iterator, {
get: function() {
callCount += 1;
}
});
function* g() {
yield iterSpy;
}
var iter = g();
var result;
result = iter.next();
assert.sameValue(result.value, iterSpy);
assert.sameValue(result.done, false);
assert.sameValue(callCount, 0);
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(callCount, 0);

View File

@ -0,0 +1,42 @@
// 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-generator-function-definitions
es6id: 14.4
description: >
YieldExpression accepts a regular expression literal as its right-hand side
info: >
The syntactic context immediately following yield requires use of the
InputElementRegExpOrTemplateTail lexical goal.
---*/
var complete = false;
var sent = {};
var iter, iterResult, received;
// Unused variables declared to improve error messages in incorrect parsing
// scenarios.
var abc, i;
function* g() {
received = yield/abc/i;
complete = true;
}
iter = g();
assert.sameValue(complete, false, 'generator initially paused');
assert.sameValue(received, undefined, 'first statement no executed');
iterResult = iter.next();
assert.sameValue(complete, false, 'generator paused following expression');
assert.sameValue(received, undefined, 'first statement not executed');
assert.sameValue(iterResult.done, false, 'iteration not complete');
assert.sameValue(iterResult.value.test('ABC'), true, 'first iterated value');
iterResult = iter.next(sent);
assert.sameValue(received, sent, 'YieldExpression value');
assert.sameValue(complete, true, 'generator correctly re-started');
assert.sameValue(iterResult.done, true, 'iteration complete');
assert.sameValue(iterResult.value, undefined, 'second iterated value');

View File

@ -0,0 +1,37 @@
// 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-generator-function-definitions
es6id: 14.4
description: YieldExpression may be followed by a TemplateMiddle construct
info: >
The syntactic context immediately following yield requires use of the
InputElementRegExpOrTemplateTail lexical goal.
---*/
var complete = false;
var iter, iterResult, str;
function* g() {
str = `1${ yield }3${ 4 }5`;
complete = true;
}
iter = g();
assert.sameValue(complete, false, 'generator initially paused');
assert.sameValue(str, undefined, 'first statement not executed');
iterResult = iter.next();
assert.sameValue(complete, false, 'generator paused following expression');
assert.sameValue(str, undefined, 'first statement not executed');
assert.sameValue(iterResult.done, false, 'iteration not complete');
assert.sameValue(iterResult.value, undefined, 'first iterated value');
iterResult = iter.next(2);
assert.sameValue(str, '12345', 'YieldExpression value');
assert.sameValue(complete, true, 'generator correctly re-started');
assert.sameValue(iterResult.done, true, 'iteration complete');
assert.sameValue(iterResult.value, undefined, 'second iterated value');

View File

@ -0,0 +1,30 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: GetValue invoked on Reference value
info: |
YieldExpression : yield AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
---*/
var err;
function* g() {
try {
yield test262unresolvable;
} catch (_err) {
err = _err;
}
}
var iter = g();
var result;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof err, 'object');
assert.sameValue(err.constructor, ReferenceError);

View File

@ -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-generator-function-definitions
es6id: 14.4
description: >
YieldExpression operand may not include the `in` keyword in contexts where it
is disallowed
info: |
Syntax
yield [no LineTerminator here] * AssignmentExpression[?In, +Yield]
negative: SyntaxError
---*/
function* g() {
for (yield * '' in {}; ; ) ;
}

View File

@ -0,0 +1,48 @@
// 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-generator-function-definitions
es6id: 14.4
description: >
YieldExpression contextually recognizes the `in` keyword as part of a
RelationalExpression
info: |
Syntax
yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
features: [Symbol.iterator]
---*/
var obj = Object.create({ hit: true });
var iter, iterResult, value;
Boolean.prototype[Symbol.iterator] = function* () { yield this.valueOf(); };
function* g() {
value = yield * 'hit' in obj;
value = yield * 'miss' in obj;
}
iter = g();
iterResult = iter.next('first');
assert.sameValue(iterResult.done, false, '`done` property (first iteration)');
assert.sameValue(iterResult.value, true, '`value` property (first iteration)');
assert.sameValue(
value, undefined, 'generator paused prior to evaluating AssignmentExpression'
);
iterResult = iter.next('second');
assert.sameValue(iterResult.done, false, '`done` property (second iteration)');
assert.sameValue(
iterResult.value, false, '`value` property (second iteration)'
);
assert.sameValue(value, undefined, 'value of first AssignmentExpression');
iterResult = iter.next('third');
assert.sameValue(iterResult.done, true, '`done` property (third iteration)');
assert.sameValue(
iterResult.value, undefined, '`value` property (third iteration)'
);
assert.sameValue(value, undefined, 'value of second AssignmentExpression');

View File

@ -0,0 +1,43 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when invoking the @@iterator method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
7.4.1 GetIterator
1. If method was not passed, then
a. Let method be ? GetMethod(obj, @@iterator).
2. Let iterator be ? Call(method, obj).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
badIter[Symbol.iterator] = function() {
throw thrown;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
assert.sameValue(caught, undefined, 'method is not invoked eagerly');
result = iter.next();
assert.sameValue(result.value, undefined, 'iteration value');
assert.sameValue(result.done, true, 'iteration status');
assert.sameValue(caught, thrown, 'error value');

View File

@ -0,0 +1,42 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: TypeError thrown when @@iterator method returns a non-object value
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
7.4.1 GetIterator
1. If method was not passed, then
a. Let method be ? GetMethod(obj, @@iterator).
2. Let iterator be ? Call(method, obj).
3. If Type(iterator) is not Object, throw a TypeError exception.
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return 7;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,43 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when accessing the @@iterator property
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
7.4.1 GetIterator
1. If method was not passed, then
a. Let method be ? GetMethod(obj, @@iterator).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var poisonedIter = Object.defineProperty({}, Symbol.iterator, {
get: function() {
throw thrown;
}
});
function* g() {
try {
yield * poisonedIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
assert.sameValue(caught, undefined, 'property is not accessed eagerly');
result = iter.next();
assert.sameValue(result.value, undefined, 'iteration value');
assert.sameValue(result.done, true, 'iteration status');
assert.sameValue(caught, thrown, 'error value');

View File

@ -0,0 +1,50 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when invoking iterator `next` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
7.4.2 IteratorNext
1. If value was not passed, then
[...]
2. Else,
a. Let result be ? Invoke(iterator, "next", « value »).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
throw thrown;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,51 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
TypeError thrown when iterator `next` method returns a non-object value
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
7.4.2 IteratorNext
1. If value was not passed, then
[...]
2. Else,
a. Let result be ? Invoke(iterator, "next", « value »).
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return 8;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,51 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when accessing iterator `next` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
7.4.2 IteratorNext
1. If value was not passed, then
[...]
2. Else,
a. Let result be ? Invoke(iterator, "next", « value »).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedNext = Object.defineProperty({}, 'next', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return poisonedNext;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,52 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Invocation of iterator `next` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
7.4.2 IteratorNext
1. If value was not passed, then
[...]
2. Else,
a. Let result be ? Invoke(iterator, "next", « value »).
[...]
features: [Symbol.iterator]
---*/
var args, thisValue;
var callCount = 0;
var spyIterator = {
next: function() {
callCount += 1;
args = arguments;
thisValue = this;
return { done: true };
}
};
var spyIterable = {};
spyIterable[Symbol.iterator] = function() {
return spyIterator;
};
function* g() {
yield * spyIterable;
}
var iter = g();
iter.next(9876);
assert.sameValue(callCount, 1);
assert.sameValue(args.length, 1);
assert.sameValue(args[0], undefined);
assert.sameValue(thisValue, spyIterator);

View File

@ -0,0 +1,53 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `done` property of iteration result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
ii. Let done be ? IteratorComplete(innerResult).
7.4.3 IteratorComplete
1. Assert: Type(iterResult) is Object.
2. Return ToBoolean(? Get(iterResult, "done")).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedDone = Object.defineProperty({}, 'done', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return poisonedDone;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,60 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
`value` property is not accessed when iteration is incomplete
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
ii. Let done be ? IteratorComplete(innerResult).
iii. If done is true, then
1. Return ? IteratorValue(innerResult).
features: [Symbol.iterator]
---*/
var badIter = {};
var callCount = 0;
var spyValue = Object.defineProperty({ done: false }, 'value', {
get: function() {
callCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return spyValue;
}
};
};
var delegationComplete = false;
function* g() {
yield * badIter;
delegationComplete = true;
}
var iter = g();
iter.next();
assert.sameValue(callCount, 0, 'access count (first iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (first iteration)'
);
iter.next();
assert.sameValue(callCount, 0, 'access count (second iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (second iteration)'
);
spyValue.done = true;
iter.next();
assert.sameValue(callCount, 1, 'access count (final iteration)');
assert.sameValue(delegationComplete, true, 'delegation complete');

View File

@ -0,0 +1,56 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `value` property of iteration
result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
ii. Let done be ? IteratorComplete(innerResult).
iii. If done is true, then
1. Return ? IteratorValue(innerResult).
7.4.4 IteratorValue
1. Assert: Type(iterResult) is Object.
2. Return ? Get(iterResult, "value").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedValue = Object.defineProperty({ done: true }, 'value', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return poisonedValue;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
result = iter.next();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,62 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Value received from invocation of generator's `next` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
ii. Let done be ? IteratorComplete(innerResult).
iii. If done is true, then
1. Return ? IteratorValue(innerResult).
7.4.4 IteratorValue
1. Assert: Type(iterResult) is Object.
2. Return ? Get(iterResult, "value").
features: [Symbol.iterator]
---*/
var quickIter = {};
var exprValue, nextReceived, done, iter;
quickIter[Symbol.iterator] = function() {
return {
next: function(x) {
nextReceived = x;
return {
done: done,
value: 3333
};
}
};
};
function* g() {
exprValue = yield * quickIter;
}
done = true;
iter = g();
iter.next(4444);
assert.sameValue(
nextReceived, undefined, 'received value (previously-exhausted iterator)'
);
assert.sameValue(exprValue, 3333, 'expression value (previously-exhausted iterator)');
done = false;
exprValue = null;
iter = g();
iter.next(2222);
done = true;
iter.next(5555);
assert.sameValue(nextReceived, 5555, 'received value');
assert.sameValue(exprValue, 3333, 'expression value');

View File

@ -0,0 +1,76 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
"Return" completion returned when `return` method is not defined
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
features: [Symbol.iterator]
---*/
var badIter = {};
var throwCount = 0;
var returnCount = 0;
var hitNextStatement = false;
var hitCatch = false;
var hitFinally = false;
var spyResult = {
next: function() {
return { done: false };
}
};
Object.defineProperty(spyResult, 'throw', {
get: function() {
throwCount += 1;
}
});
Object.defineProperty(spyResult, 'return', {
get: function() {
returnCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return spyResult;
};
function* g() {
try {
yield * badIter;
hitNextStatement = true;
} catch (_) {
hitCatch = true;
} finally {
hitFinally = true;
}
}
var iter = g();
iter.next();
iter.return();
assert.sameValue(throwCount, 0, '`throw` property access');
assert.sameValue(returnCount, 1, '`return` property access');
assert.sameValue(
hitFinally, true, 'Generator execution was resumed'
);
assert.sameValue(
hitNextStatement, false, 'Abrupt completion interrupted control flow'
);
assert.sameValue(
hitCatch, false, 'Abrupt completion not interpreted as "throw"'
);

View File

@ -0,0 +1,67 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `done` property of iteration result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
v. If Type(innerReturnResult) is not Object, throw a TypeError
exception.
vi. Let done be ? IteratorComplete(innerReturnResult).
7.4.3 IteratorComplete
1. Assert: Type(iterResult) is Object.
2. Return ToBoolean(? Get(iterResult, "done")).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedDone = Object.defineProperty({}, 'done', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
return poisonedDone;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.return();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,91 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
`value` property is not accessed when iteration is incomplete
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
v. If Type(innerReturnResult) is not Object, throw a TypeError
exception.
vi. Let done be ? IteratorComplete(innerReturnResult).
vii. If done is true, then
1. Let value be ? IteratorValue(innerReturnResult).
2. Return Completion{[[Type]]: return, [[Value]]: value,
[[Target]]: empty}.
viii. Let received be GeneratorYield(innerReturnResult).
7.4.3 IteratorComplete
1. Assert: Type(iterResult) is Object.
2. Return ToBoolean(? Get(iterResult, "done")).
features: [Symbol.iterator]
---*/
var badIter = {};
var callCount = 0;
var spyValue = Object.defineProperty({ done: false }, 'value', {
get: function() {
callCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
return spyValue;
}
};
};
var normalCompletion = false;
var errorCompletion = false;
var delegationComplete = false;
function* g() {
try {
yield * badIter;
normalCompletion = true;
} catch (_) {
errorCompletion = true;
} finally {
delegationComplete = true;
}
}
var iter = g();
iter.next();
assert.sameValue(callCount, 0, 'access count (first iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (first iteration)'
);
iter.return();
assert.sameValue(callCount, 0, 'access count (second iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (second iteration)'
);
spyValue.done = true;
iter.return();
assert.sameValue(callCount, 1, 'access count (final iteration)');
assert.sameValue(delegationComplete, true, 'delegation complete');
assert.sameValue(normalCompletion, false, 'completion was abrupt');
assert.sameValue(errorCompletion, false, 'completion was not of type "throw"');

View File

@ -0,0 +1,70 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `value` property of iteration
result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
v. If Type(innerReturnResult) is not Object, throw a TypeError
exception.
vi. Let done be ? IteratorComplete(innerReturnResult).
vii. If done is true, then
1. Let value be ? IteratorValue(innerReturnResult).
7.4.4 IteratorValue
1. Assert: Type(iterResult) is Object.
2. Return ? Get(iterResult, "value").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedValue = Object.defineProperty({ done: true }, 'value', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
return poisonedValue;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.return();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,71 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Value received from invocation of generator's `return` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
v. If Type(innerReturnResult) is not Object, throw a TypeError
exception.
vi. Let done be ? IteratorComplete(innerReturnResult).
vii. If done is true, then
1. Let value be ? IteratorValue(innerReturnResult).
2. Return Completion{[[Type]]: return, [[Value]]: value,
[[Target]]: empty}.
viii. Let received be GeneratorYield(innerReturnResult).
features: [Symbol.iterator]
---*/
var quickIter = {};
var normalCompletion = false;
var errorCompletion = false;
var delegationComplete = false;
var iter, returnReceived;
quickIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function(x) {
returnReceived = x;
return { done: true, value: 3333 };
}
};
};
function* g() {
try {
yield * quickIter;
normalCompletion = true;
} catch (e) {
errorCompletion = true;
} finally {
delegationComplete = true;
}
}
iter = g();
iter.next();
iter.return(2222);
assert.sameValue(returnReceived, 2222);
assert.sameValue(delegationComplete, true, 'delegation complete');
assert.sameValue(normalCompletion, false, 'completion was abrupt');
assert.sameValue(errorCompletion, false, 'completion was not of type "throw"');

View File

@ -0,0 +1,55 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when invoking iterator `return` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
throw thrown;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
result = iter.return();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,58 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
TypeError thrown when iterator `return` method returns a non-object value
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
v. If Type(innerReturnResult) is not Object, throw a TypeError
exception.
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
return 23;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
result = iter.return();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,65 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when accessing iterator `return` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var callCount = 0;
var poisonedReturn = {
next: function() {
return { done: false };
}
};
Object.defineProperty(poisonedReturn, 'throw', {
get: function() {
callCount += 1;
}
});
Object.defineProperty(poisonedReturn, 'return', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return poisonedReturn;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
assert.sameValue(caught, undefined, '`return` property not accessed eagerly');
result = iter.return();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);
assert.sameValue(callCount, 0, 'iterator `throw` property is not accessed');

View File

@ -0,0 +1,57 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Invocation of iterator `return` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
[...]
c. Else,
i. Assert: received.[[Type]] is return.
ii. Let return be ? GetMethod(iterator, "return").
iii. If return is undefined, return Completion(received).
iv. Let innerReturnResult be ? Call(return, iterator, «
received.[[Value]] »).
[...]
features: [Symbol.iterator]
---*/
var args, thisValue;
var callCount = 0;
var spyIterator = {
next: function() {
return { done: false };
},
return: function() {
callCount += 1;
args = arguments;
thisValue = this;
return { done: true };
}
};
var spyIterable = {};
spyIterable[Symbol.iterator] = function() {
return spyIterator;
};
function* g() {
yield * spyIterable;
}
var iter = g();
iter.next(8888);
iter.return(7777);
assert.sameValue(callCount, 1);
assert.sameValue(args.length, 1);
assert.sameValue(args[0], 7777);
assert.sameValue(thisValue, spyIterator);

View File

@ -0,0 +1,66 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `done` property of iteration result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
2. NOTE: Exceptions from the inner iterator throw method are
propagated. Normal completions from an inner throw method are
processed similarly to an inner next.
3. If Type(innerResult) is not Object, throw a TypeError exception.
4. Let done be ? IteratorComplete(innerResult).
7.4.3 IteratorComplete
1. Assert: Type(iterResult) is Object.
2. Return ToBoolean(? Get(iterResult, "done")).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedDone = Object.defineProperty({}, 'done', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function() {
return poisonedDone;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,76 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
description: >
`value` property is not accessed when iteration is complete
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
2. NOTE: Exceptions from the inner iterator throw method are
propagated. Normal completions from an inner throw method are
processed similarly to an inner next.
3. If Type(innerResult) is not Object, throw a TypeError exception.
4. Let done be ? IteratorComplete(innerResult).
5. If done is true, then
a. Return ? IteratorValue(innerResult).
7.4.3 IteratorComplete
1. Assert: Type(iterResult) is Object.
2. Return ToBoolean(? Get(iterResult, "done")).
features: [Symbol.iterator]
---*/
var badIter = {};
var callCount = 0;
var spyValue = Object.defineProperty({ done: false }, 'value', {
get: function() {
callCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function() {
return spyValue;
}
};
};
var delegationComplete = false;
function* g() {
yield * badIter;
delegationComplete = true;
}
var iter = g();
iter.next();
assert.sameValue(callCount, 0, 'access count (first iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (first iteration)'
);
iter.throw();
assert.sameValue(callCount, 0, 'access count (second iteration)');
assert.sameValue(
delegationComplete, false, 'delegation ongoing (second iteration)'
);
spyValue.done = true;
iter.throw();
assert.sameValue(callCount, 1, 'access count (final iteration)');
assert.sameValue(delegationComplete, true, 'delegation complete');

View File

@ -0,0 +1,69 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing `value` property of iteration
result
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
2. NOTE: Exceptions from the inner iterator throw method are
propagated. Normal completions from an inner throw method are
processed similarly to an inner next.
3. If Type(innerResult) is not Object, throw a TypeError exception.
4. Let done be ? IteratorComplete(innerResult).
5. If done is true, then
a. Return ? IteratorValue(innerResult).
7.4.4 IteratorValue
1. Assert: Type(iterResult) is Object.
2. Return ? Get(iterResult, "value").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedValue = Object.defineProperty({ done: true }, 'value', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function() {
return poisonedValue;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,54 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
description: Value received from invocation of generator's `throw` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
2. NOTE: Exceptions from the inner iterator throw method are
propagated. Normal completions from an inner throw method are
processed similarly to an inner next.
3. If Type(innerResult) is not Object, throw a TypeError exception.
4. Let done be ? IteratorComplete(innerResult).
5. If done is true, then
[...]
6. Let received be GeneratorYield(innerResult).
features: [Symbol.iterator]
---*/
var quickIter = {};
var iter, exprValue, throwReceived;
quickIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function(x) {
throwReceived = x;
return { done: true, value: 3333 };
}
};
};
function* g() {
exprValue = yield * quickIter;
}
iter = g();
iter.next();
iter.throw(2222);
assert.sameValue(throwReceived, 2222);
assert.sameValue(exprValue, 3333);

View File

@ -0,0 +1,52 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when invoking iterator `throw` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function() {
throw thrown;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
result = iter.throw();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,57 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
TypeError thrown when iterator `throw` method returns a non-object value
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
2. NOTE: Exceptions from the inner iterator throw method are
propagated. Normal completions from an inner throw method are
processed similarly to an inner next.
3. If Type(innerResult) is not Object, throw a TypeError exception.
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
throw: function() {
return 23;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
result = iter.throw();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,55 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Abrupt completion returned when accessing iterator `throw` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var poisonedThrow = {
next: function() {
return { done: false };
}
};
Object.defineProperty(poisonedThrow, 'throw', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return poisonedThrow;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var result, caught;
iter.next();
assert.sameValue(caught, undefined, '`throw` property not accesed eagerly');
result = iter.throw();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,54 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: Invocation of iterator `throw` method
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
»).
[...]
features: [Symbol.iterator]
---*/
var args, thisValue;
var callCount = 0;
var spyIterator = {
next: function() {
return { done: false };
},
throw: function() {
callCount += 1;
args = arguments;
thisValue = this;
return { done: true };
}
};
var spyIterable = {};
spyIterable[Symbol.iterator] = function() {
return spyIterator;
};
function* g() {
yield * spyIterable;
}
var iter = g();
iter.next(8888);
iter.throw(7777);
assert.sameValue(callCount, 1);
assert.sameValue(args.length, 1);
assert.sameValue(args[0], 7777);
assert.sameValue(thisValue, spyIterator);

View File

@ -0,0 +1,80 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned after protocol violation (and a `return` method
is not defined)
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
[...]
iii. Else,
1. NOTE: If iterator does not have a throw method, this throw is
going to terminate the yield* loop. But first we need to give
iterator a chance to clean up.
2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
[[Value]]: empty, [[Target]]: empty}).
3. NOTE: The next step throws a TypeError to indicate that there
was a yield* protocol violation: iterator does not have a throw
method.
4. Throw a TypeError exception.
7.4.6 IteratorClose
1. Assert: Type(iterator) is Object.
2. Assert: completion is a Completion Record.
3. Let return be ? GetMethod(iterator, "return").
4. If return is undefined, return Completion(completion).
features: [Symbol.iterator]
---*/
var badIter = {};
var throwCount = 0;
var returnCount = 0;
var spyResult = {
next: function() {
return { done: false };
}
};
Object.defineProperty(spyResult, 'throw', {
get: function() {
throwCount += 1;
}
});
Object.defineProperty(spyResult, 'return', {
get: function() {
returnCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return spyResult;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(throwCount, 1, '`throw` property access');
assert.sameValue(returnCount, 1, '`return` property access');
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,71 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when invoking iterator `return` method following
protocol violation
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
[...]
iii. Else,
1. NOTE: If iterator does not have a throw method, this throw is
going to terminate the yield* loop. But first we need to give
iterator a chance to clean up.
2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
[[Value]]: empty, [[Target]]: empty}).
7.4.6 IteratorClose
1. Assert: Type(iterator) is Object.
2. Assert: completion is a Completion Record.
3. Let return be ? GetMethod(iterator, "return").
4. If return is undefined, return Completion(completion).
5. Let innerResult be Call(return, iterator, « »).
6. If completion.[[Type]] is throw, return Completion(completion).
7. If innerResult.[[Type]] is throw, return Completion(innerResult).
8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
// Using a primitive completion value ensures that the check for the type
// of the completion value (and resulting TypeError) occurs *after* the
// check for the type of the completion itself (which is the behavior
// under test).
throw 87;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(caught, 87);

View File

@ -0,0 +1,68 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Non-object value returned by iterator `return` method following protocol
violation
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
[...]
iii. Else,
1. NOTE: If iterator does not have a throw method, this throw is
going to terminate the yield* loop. But first we need to give
iterator a chance to clean up.
2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
[[Value]]: empty, [[Target]]: empty}).
7.4.6 IteratorClose
1. Assert: Type(iterator) is Object.
2. Assert: completion is a Completion Record.
3. Let return be ? GetMethod(iterator, "return").
4. If return is undefined, return Completion(completion).
5. Let innerResult be Call(return, iterator, « »).
6. If completion.[[Type]] is throw, return Completion(completion).
7. If innerResult.[[Type]] is throw, return Completion(innerResult).
8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
features: [Symbol.iterator]
---*/
var badIter = {};
badIter[Symbol.iterator] = function() {
return {
next: function() {
return { done: false };
},
return: function() {
return 87;
}
};
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(typeof caught, 'object');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,73 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned when accessing iterator `return` property after
protocol violation
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
[...]
iii. Else,
1. NOTE: If iterator does not have a throw method, this throw is
going to terminate the yield* loop. But first we need to give
iterator a chance to clean up.
2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
[[Value]]: empty, [[Target]]: empty}).
7.4.6 IteratorClose
1. Assert: Type(iterator) is Object.
2. Assert: completion is a Completion Record.
3. Let return be ? GetMethod(iterator, "return").
features: [Symbol.iterator]
---*/
var thrown = new Test262Error();
var badIter = {};
var callCount = 0;
var poisonedReturn = {
next: function() {
return { done: false };
}
};
Object.defineProperty(poisonedReturn, 'throw', {
get: function() {
callCount += 1;
}
});
Object.defineProperty(poisonedReturn, 'return', {
get: function() {
throw thrown;
}
});
badIter[Symbol.iterator] = function() {
return poisonedReturn;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(callCount, 1);
assert.sameValue(caught, thrown);

View File

@ -0,0 +1,89 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: >
Abrupt completion returned after protocol violation (and a `return` method
is defined)
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Let iterator be ? GetIterator(value).
4. Let received be NormalCompletion(undefined).
5. Repeat
a. If received.[[Type]] is normal, then
[...]
b. Else if received.[[Type]] is throw, then
i. Let throw be ? GetMethod(iterator, "throw").
ii. If throw is not undefined, then
[...]
iii. Else,
1. NOTE: If iterator does not have a throw method, this throw is
going to terminate the yield* loop. But first we need to give
iterator a chance to clean up.
2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
[[Value]]: empty, [[Target]]: empty}).
3. NOTE: The next step throws a TypeError to indicate that there
was a yield* protocol violation: iterator does not have a throw
method.
4. Throw a TypeError exception.
7.4.6 IteratorClose
1. Assert: Type(iterator) is Object.
2. Assert: completion is a Completion Record.
3. Let return be ? GetMethod(iterator, "return").
4. If return is undefined, return Completion(completion).
5. Let innerResult be Call(return, iterator, « »).
6. If completion.[[Type]] is throw, return Completion(completion).
7. If innerResult.[[Type]] is throw, return Completion(innerResult).
8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
9. Return Completion(completion).
features: [Symbol.iterator]
---*/
var badIter = {};
var throwCount = 0;
var thisValue, args;
var poisonedReturn = {
next: function() {
return { done: false };
},
return: function() {
thisValue = this;
args = arguments;
return 'this value has no effect on the protocol';
}
};
Object.defineProperty(poisonedReturn, 'throw', {
get: function() {
throwCount += 1;
}
});
badIter[Symbol.iterator] = function() {
return poisonedReturn;
};
function* g() {
try {
yield * badIter;
} catch (err) {
caught = err;
}
}
var iter = g();
var caught;
iter.next();
iter.throw();
assert.sameValue(throwCount, 1);
assert.sameValue(thisValue, poisonedReturn, '"this" value');
assert.sameValue(
typeof args, 'object', 'method invoked, arguments object provided'
);
assert.sameValue(args.length, 0);
assert.sameValue(typeof caught, 'object', 'object value thrown');
assert.sameValue(caught.constructor, TypeError);

View File

@ -0,0 +1,30 @@
// 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-generator-function-definitions-runtime-semantics-evaluation
es6id: 14.4.14
description: GetValue invoked on Reference value
info: |
YieldExpression : yield * AssignmentExpression
1. Let exprRef be the result of evaluating AssignmentExpression.
2. Let value be ? GetValue(exprRef).
---*/
var err;
function* g() {
try {
yield * test262unresolvable;
} catch (_err) {
err = _err;
}
}
var iter = g();
var result;
result = iter.next();
assert.sameValue(result.value, undefined);
assert.sameValue(result.done, true);
assert.sameValue(typeof err, 'object');
assert.sameValue(err.constructor, ReferenceError);