summaryrefslogtreecommitdiffstats
path: root/js/src/builtin
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-15 21:12:03 +0100
committerjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-15 21:12:03 +0100
commit25550ce903d01f31bead59de945e4adf86819440 (patch)
tree25fbd8c0ef297a8252d67a1dde50e94db1abd8ec /js/src/builtin
parent75c9377766326589faa844a95d5997a156f6aed0 (diff)
downloadUXP-25550ce903d01f31bead59de945e4adf86819440.tar
UXP-25550ce903d01f31bead59de945e4adf86819440.tar.gz
UXP-25550ce903d01f31bead59de945e4adf86819440.tar.lz
UXP-25550ce903d01f31bead59de945e4adf86819440.tar.xz
UXP-25550ce903d01f31bead59de945e4adf86819440.zip
Close iterator after error in Array.from
Issue #17
Diffstat (limited to 'js/src/builtin')
-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;
+ }
}
}