summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/Array.js
diff options
context:
space:
mode:
authorMoonchild <mcwerewolf@gmail.com>2018-03-16 08:36:30 +0100
committerGitHub <noreply@github.com>2018-03-16 08:36:30 +0100
commit11bdaa144d8a38ecd897dde278cb1db9b8313961 (patch)
tree1ca375db23843dcd4c593bcb28d7173856bddc10 /js/src/builtin/Array.js
parent0d3ee51ad2d61bffba14232b2df913d3a773d771 (diff)
parent114794557687aebca601c38ba0f0a52a43b44d4a (diff)
downloadUXP-11bdaa144d8a38ecd897dde278cb1db9b8313961.tar
UXP-11bdaa144d8a38ecd897dde278cb1db9b8313961.tar.gz
UXP-11bdaa144d8a38ecd897dde278cb1db9b8313961.tar.lz
UXP-11bdaa144d8a38ecd897dde278cb1db9b8313961.tar.xz
UXP-11bdaa144d8a38ecd897dde278cb1db9b8313961.zip
Merge pull request #66 from janekptacijarabaci/js_iterable_closures_1
Close iterator after error in: Map, Set, WeakMap, WeakSet, Array.from, Promise.{all,race}
Diffstat (limited to 'js/src/builtin/Array.js')
-rw-r--r--js/src/builtin/Array.js46
1 files changed, 32 insertions, 14 deletions
diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js
index 54b47b72f..5ab0b71be 100644
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -784,7 +784,7 @@ function ArrayKeys() {
return CreateArrayIterator(this, ITEM_KIND_KEY);
}
-// ES6 draft rev31 (2015/01/15) 22.1.2.1 Array.from(source[, mapfn[, thisArg]]).
+// ES 2017 draft 0f10dba4ad18de92d47d421f378233a2eae8f077 22.1.2.1
function ArrayFrom(items, mapfn=undefined, thisArg=undefined) {
// Step 1.
var C = this;
@@ -795,43 +795,61 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn));
var T = thisArg;
- // Steps 4-5.
+ // Step 4.
var usingIterator = GetMethod(items, std_iterator);
- // Step 6.
+ // Step 5.
if (usingIterator !== undefined) {
- // Steps 6.a-c.
+ // Steps 5.a-c.
var A = IsConstructor(C) ? new C() : [];
- // Steps 6.d-e.
+ // Step 5.c.
var iterator = GetIterator(items, usingIterator);
- // Step 6.f.
+ // Step 5.d.
var k = 0;
- // Step 6.g.
+ // Step 5.e.
// These steps cannot be implemented using a for-of loop.
// See <https://bugs.ecmascript.org/show_bug.cgi?id=2883>.
while (true) {
- // Steps 6.g.i-iii.
+ // Step 5.e.i.
+ // Disabled for performance reason. We won't hit this case on
+ // normal array, since _DefineDataProperty will throw before it.
+ // We could hit this when |A| is a proxy and it ignores
+ // |_DefineDataProperty|, but it happens only after too long loop.
+ /*
+ if (k >= 0x1fffffffffffff) {
+ IteratorCloseThrow(iterator);
+ ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
+ }
+ */
+
+ // Step 5.e.iii.
var next = callContentFunction(iterator.next, iterator);
if (!IsObject(next))
ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE);
- // Step 6.g.iv.
+ // Step 5.e.iv.
if (next.done) {
A.length = k;
return A;
}
- // Steps 6.g.v-vi.
+ // Steps 5.e.v.
var nextValue = next.value;
- // Steps 6.g.vii-viii.
- var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue;
+ // Steps 5.e.vi-vii.
+ try {
+ var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue;
- // Steps 6.g.ix-xi.
- _DefineDataProperty(A, k++, mappedValue);
+ // Steps 5.e.ii (reordered), 5.e.viii.
+ _DefineDataProperty(A, k++, mappedValue);
+ } catch (e) {
+ // Steps 5.e.vi.2, 5.e.ix.
+ IteratorCloseThrow(iterator);
+ throw e;
+ }
}
}