mirror of https://github.com/tc39/test262.git
Add tests for IteratorClose in dstr assignment (#524)
The files in this patch are organized according to the following naming scheme: Prefix | Grammar production -------------------|------------------- `array-empty-` | ArrayAssignmentPattern : [ ] `array-elision-` | ArrayAssignmentPattern : [ Elision ] `array-rest-` | ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ] `array-elem-` | ArrayAssignmentPattern : [ AssignmentElementList ] `array-elem-trlg-` | ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ] Suffix | Intent -------------------|------- `-abpt-close-err` | The assignment evaluation returns an abrupt completion, and the iterator's `return` method throws an error `-abpt-close-skip` | The assignment evaluation returns an abrupt completion, but IteratorClose is not invoked `-abpt-close` | The assignment evaluation returns an abrupt completion, and IteratorClose is invoked as specified `-get-err` | Abrupt completion returned from GetIterator `-nrml-close-err` | The assignment evaluation completes, and the iterator's `return` method throws an error `-nrml-close-null` | The assignment evaluation completes, and the iterator's `return` method returns a non-Object value (there is no corresponding `-abpt-` suffix because the algorithm does not reference the return value in those cases) `-nrml-close-skip` | The assignment evaluation completes, but IteratorClose is not invoked `-nrml-close` | The assignment evaluation completes, and IteratorClose is invoked as specified Not all suffixes are appropriate for all productions. Suffixes have been simplified in cases where less specificity is necessary to disambiguate test cases.
This commit is contained in:
parent
a657b64ae4
commit
26676beab5
|
@ -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.
|
||||
/*---
|
||||
description: Abrupt completion returned from GetIterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var x;
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x ] = iterable;
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from IteratorClose
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var x;
|
||||
var iterable = {};
|
||||
var nextCount = 0;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[ x ] = iterable;
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when assignment evaluation has exhausted the
|
||||
iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
|
||||
6. Return result.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when assignment evaluation has not exhausted the
|
||||
iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "return"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ {}[yield] ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
iter = g();
|
||||
iter.next();
|
||||
assert.throws(Test262Error, function() {
|
||||
iter.return();
|
||||
});
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
function* g() {
|
||||
[ {}[yield] ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
iter.return();
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "return"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
var iter, result;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ {}[yield] ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
iter = g();
|
||||
iter.next();
|
||||
result = iter.return(777);
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
||||
assert.sameValue(result.value, 777);
|
||||
assert(result.done, 'Iterator correctly closed');
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "throw"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
function ReturnError() {}
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
// This value should be discarded.
|
||||
throw new ReturnError();
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ {}[thrower()] ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when iteration produces an abrupt completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
throw new Test262Error();
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
var x;
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "throw"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ AssignmentElementList ]
|
||||
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ {}[thrower()] ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: Abrupt completion returned during evaluation of elision
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
6. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
i. If iteratorRecord.[[done]] is false, return
|
||||
IteratorClose(iterator, status).
|
||||
ii. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
|
||||
if (nextCount === 2) {
|
||||
throw new Test262Error();
|
||||
}
|
||||
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 2);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from IteratorClose
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
6. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
[...]
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 2);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
6. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
[...]
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var x;
|
||||
var nextCount = 0;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[ x , , ] = iterable;
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: IteratorClose not invoked when elision exhausts the iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
6. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
[...]
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
|
||||
return { done: nextCount > 1 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x , , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 2);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: IteratorClose invoked when elision does not exhaust the iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
6. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
[...]
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x , , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 2);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from GetIterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var x;
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ] = iterable;
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from IteratorClose
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var x;
|
||||
var nextCount = 0;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[ x , ] = iterable;
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not invoked when evaluation of AssignmentElementList
|
||||
exhausts the iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is invoked when evaluation of AssignmentElementList completes
|
||||
without exhausting the iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is invoked when evaluation of AssignmentElementList returns
|
||||
a "return" completion and the iterator has not been marked as "done"
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ {}[yield] , ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
assert.throws(Test262Error, function() {
|
||||
iter.return();
|
||||
});
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ {}[yield] , ] = iterable;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
iter.return();
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is invoked when evaluation of AssignmentElementList returns
|
||||
a "return" completion and the iterator has not been marked as "done"
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
var iter, result;
|
||||
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ {}[yield] , ] = iterable;
|
||||
unreachable += 1;
|
||||
};
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
result = iter.return(888);
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
||||
assert.sameValue(result.value, 888);
|
||||
assert(result.done, 'Iterator correctly closed');
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is invoked when evaluation of AssignmentElementList returns
|
||||
a "throw" completion and the iterator has not been marked as "done"
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
function ReturnError() {}
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
// This value should be discarded.
|
||||
throw new ReturnError();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ {}[thrower()] , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not invoked when evaluation of AssignmentElementList
|
||||
returns an abrupt completion and the iterator has been marked as "done"
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
throw new Test262Error();
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
var x;
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is invoked when evaluation of AssignmentElementList returns
|
||||
a "throw" completion and the iterator has not been marked as "done"
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
|
||||
4. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
|
||||
iteratorRecord as the argument.
|
||||
5. If status is an abrupt completion, then
|
||||
a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
b. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ {}[thrower()] , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when rest element evaluation has exhausted the
|
||||
iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var x, y;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { value: nextCount, done: nextCount > 1 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ x , ...y ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 2, 'nextCount');
|
||||
assert.sameValue(returnCount, 0, 'returnCount');
|
||||
assert.sameValue(x, 1, 'x');
|
||||
assert.sameValue(y.length, 0, 'y.length');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when AssignmentRestEvaluation produces a "return"
|
||||
completion due to reference evaluation
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
function* g() {
|
||||
[ x , ...{}[yield] ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
iter.return();
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ x , ...{}[yield] ] = iterable;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
iter.return();
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when AssignmentRestEvaluation produces a "return"
|
||||
completion due to reference evaluation
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
var iter, result;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[ x , ...{}[yield] ] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
result = iter.return(999);
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
||||
assert.sameValue(result.value, 999);
|
||||
assert(result.done, 'Iterator correctly closed');
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when AssignmentRestEvaluation produces a "throw"
|
||||
completion due to reference evaluation
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
7. If completion.[[type]] is throw, return Completion(completion)
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
function ReturnError() {}
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
// This value should be discarded.
|
||||
throw new ReturnError();
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ...{}[thrower()] ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: Abrupt completion returned during iteration for rest element
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
|
||||
if (nextCount === 2) {
|
||||
throw new Test262Error();
|
||||
}
|
||||
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ...x ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 2);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when AssignmentRestEvaluation produces a "throw"
|
||||
completion due to reference evaluation
|
||||
info: |
|
||||
ArrayAssignmentPattern :
|
||||
[ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
|
||||
|
||||
[...]
|
||||
7. If AssignmentRestElement is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
|
||||
with iteratorRecord as the argument.
|
||||
8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
status).
|
||||
9. Return Completion(status).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var x;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ x , ...{}[thrower()] ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when iteration produces an abrupt completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
throw new Test262Error();
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from GetIterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ , ] = iterable;
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
Abrupt completion returned from IteratorClose
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
6. Return result.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ , ] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
[...]
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var nextCount = 0;
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[ , ] = iterable;
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when iteration has exhausted the iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when assignment evaluation has not exhausted the
|
||||
iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elision ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
[...]
|
||||
5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
[...]
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ , ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
/*---
|
||||
description: >
|
||||
A sparse ArrayAssignmentPattern without an AssignmentElementList requires
|
||||
iterable values and throws for other values.
|
||||
An ArrayAssignmentPattern containing only Elisions requires iterable values
|
||||
and throws for other values.
|
||||
es6id: 12.14.5.2
|
||||
---*/
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from IteratorClose
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
3. Return IteratorClose(iterator, NormalCompletion(empty)).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
3. Return IteratorClose(iterator, NormalCompletion(empty)).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
|
||||
exception.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[] = iterable;
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Iterator is closed without iterating
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
3. Return IteratorClose(iterator, NormalCompletion(empty)).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Abrupt completion returned from GetIterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[] = iterable;
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when assignment evaluation produces an abrupt
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
4. If Elision is present, then
|
||||
a. Let status be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of Elision with
|
||||
iteratorRecord as the argument.
|
||||
b. If status is an abrupt completion, then
|
||||
i. If iteratorRecord.[[done]] is false, return
|
||||
IteratorClose(iterator, status).
|
||||
ii. Return Completion(status).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
throw new Test262Error();
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
var x;
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[ , ...x] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: Abrupt completion returned from GetIterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
1. Let iterator be GetIterator(value).
|
||||
2. ReturnIfAbrupt(iterator).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var x;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...x] = iterable;
|
||||
});
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when assignment evaluation has exhausted the
|
||||
iterator
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
7. Return result.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[ ...x ] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "return"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
function ReturnError() {}
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[...{}[yield]] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
assert.throws(Test262Error, function() {
|
||||
iter.return();
|
||||
});
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose throws a TypeError when `return` returns a non-Object value
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
var iter;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[...{}[yield]] = iterable;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
iter.return();
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "return"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
7. If completion.[[type]] is throw, return Completion(completion).
|
||||
8. If innerResult.[[type]] is throw, return Completion(innerResult).
|
||||
features: [Symbol.iterator, generators]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var returnCount = 0;
|
||||
var unreachable = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
var iter, result;
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
function* g() {
|
||||
[...{}[yield]] = iterable;
|
||||
unreachable += 1;
|
||||
}
|
||||
|
||||
iter = g();
|
||||
iter.next();
|
||||
result = iter.return(444);
|
||||
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
|
||||
assert.sameValue(result.value, 444);
|
||||
assert(result.done, 'Iterator correctly closed');
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "throw"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
function ReturnError() {}
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
|
||||
// This value should be discarded.
|
||||
throw new ReturnError();
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...{}[thrower()]] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -0,0 +1,41 @@
|
|||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when iteration produces an abrupt completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
throw new Test262Error();
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...x] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces a "throw"
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
|
||||
7.4.6 IteratorClose( iterator, completion )
|
||||
|
||||
[...]
|
||||
6. Let innerResult be Call(return, iterator, « »).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var thisValue = null;
|
||||
var args = null;
|
||||
var x;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
// Set an upper-bound to limit unnecessary iteration in non-conformant
|
||||
// implementations
|
||||
return { done: nextCount > 10 };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
thisValue = this;
|
||||
args = arguments;
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...{}[thrower()]] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
||||
assert.sameValue(thisValue, iterator, 'correct `this` value');
|
||||
assert(!!args, 'arguments object provided');
|
||||
assert.sameValue(args.length, 0, 'zero arguments specified');
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is called when reference evaluation produces an abrupt
|
||||
completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...{}[thrower()]] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 0);
|
||||
assert.sameValue(returnCount, 1);
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: Reference is evaluated during assignment
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Let lref be the result of evaluating DestructuringAssignmentTarget.
|
||||
b. ReturnIfAbrupt(lref).
|
||||
[...]
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
var obj = {};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
[...obj['a' + 'b']] = iterable;
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
||||
assert(!!obj.ab);
|
||||
assert.sameValue(obj.ab.length, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when nested array pattern evaluation produces
|
||||
an abrupt completion
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
[...]
|
||||
4. Repeat while iteratorRecord.[[done]] is false
|
||||
[...]
|
||||
d. If next is false, set iteratorRecord.[[done]] to true.
|
||||
[...]
|
||||
7. Return the result of performing DestructuringAssignmentEvaluation of
|
||||
nestedAssignmentPattern with A as the argument.
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
var thrower = function() {
|
||||
throw new Test262Error();
|
||||
};
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[...[...{}[thrower()]]] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
|
@ -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.
|
||||
/*---
|
||||
description: >
|
||||
IteratorClose is not called when value assignment produces an abrupt
|
||||
completion.
|
||||
info: |
|
||||
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
|
||||
|
||||
[...]
|
||||
5. Let result be the result of performing
|
||||
IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
|
||||
iteratorRecord as the argument
|
||||
6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
|
||||
result).
|
||||
|
||||
AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
|
||||
|
||||
[...]
|
||||
4. Repeat while iteratorRecord.[[done]] is false
|
||||
[...]
|
||||
d. If next is false, set iteratorRecord.[[done]] to true.
|
||||
[...]
|
||||
5. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
|
||||
ArrayLiteral, then
|
||||
a. Return PutValue(lref, A).
|
||||
features: [Symbol.iterator]
|
||||
es6id: 12.14.5.2
|
||||
esid: sec-runtime-semantics-destructuringassignmentevaluation
|
||||
---*/
|
||||
|
||||
var nextCount = 0;
|
||||
var returnCount = 0;
|
||||
var iterable = {};
|
||||
var iterator = {
|
||||
next: function() {
|
||||
nextCount += 1;
|
||||
return { done: true };
|
||||
},
|
||||
return: function() {
|
||||
returnCount += 1;
|
||||
}
|
||||
};
|
||||
var obj = Object.defineProperty({}, 'poisoned', {
|
||||
set: function(x) {
|
||||
throw new Test262Error();
|
||||
}
|
||||
});
|
||||
iterable[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[...obj.poisoned] = iterable;
|
||||
});
|
||||
|
||||
assert.sameValue(nextCount, 1);
|
||||
assert.sameValue(returnCount, 0);
|
Loading…
Reference in New Issue