Bug 1147371: Convert self-hosted code that need to call IteratorClose to use for-of

Issue #74
This commit is contained in:
janekptacijarabaci 2018-03-24 12:15:02 +01:00 • committed by Roy Tam
commit aa954171ae
7 changed files with 27 additions and 192 deletions

View file

@ -803,54 +803,32 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) {
// Steps 5.a-c. // Steps 5.a-c.
var A = IsConstructor(C) ? new C() : []; var A = IsConstructor(C) ? new C() : [];
// Step 5.c.
var iterator = GetIterator(items, usingIterator);
// Step 5.d. // Step 5.d.
var k = 0; var k = 0;
// Step 5.e. // Step 5.c, 5.e.
// These steps cannot be implemented using a for-of loop. var iteratorWrapper = { [std_iterator]() { return GetIterator(items, usingIterator); } };
// See <https://bugs.ecmascript.org/show_bug.cgi?id=2883>. for (var nextValue of allowContentIter(iteratorWrapper)) {
while (true) {
// Step 5.e.i. // Step 5.e.i.
// Disabled for performance reason. We won't hit this case on // Disabled for performance reason. We won't hit this case on
// normal array, since _DefineDataProperty will throw before it. // normal array, since _DefineDataProperty will throw before it.
// We could hit this when |A| is a proxy and it ignores // We could hit this when |A| is a proxy and it ignores
// |_DefineDataProperty|, but it happens only after too long loop. // |_DefineDataProperty|, but it happens only after too long loop.
/* /*
if (k >= 0x1fffffffffffff) { if (k >= 0x1fffffffffffff)
IteratorCloseThrow(iterator);
ThrowTypeError(JSMSG_TOO_LONG_ARRAY); ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
}
*/ */
// Step 5.e.iii.
var next = callContentFunction(iterator.next, iterator);
if (!IsObject(next))
ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE);
// Step 5.e.iv.
if (next.done) {
A.length = k;
return A;
}
// Steps 5.e.v.
var nextValue = next.value;
// Steps 5.e.vi-vii. // Steps 5.e.vi-vii.
try { var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue;
var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue;
// Steps 5.e.ii (reordered), 5.e.viii. // Steps 5.e.ii (reordered), 5.e.viii.
_DefineDataProperty(A, k++, mappedValue); _DefineDataProperty(A, k++, mappedValue);
} catch (e) {
// Steps 5.e.vi.2, 5.e.ix.
IteratorCloseThrow(iterator);
throw e;
}
} }
// Step 5.e.iv.
A.length = k;
return A;
} }
// Step 7. // Step 7.

View file

@ -5,7 +5,7 @@
var DefaultDerivedClassConstructor = var DefaultDerivedClassConstructor =
class extends null { class extends null {
constructor(...args) { constructor(...args) {
super(...allowContentSpread(args)); super(...allowContentIter(args));
} }
}; };
MakeDefaultConstructor(DefaultDerivedClassConstructor); MakeDefaultConstructor(DefaultDerivedClassConstructor);

View file

@ -14,44 +14,14 @@ function MapConstructorInit(iterable) {
if (!IsCallable(adder)) if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder); ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c. // Steps 6.c-8.
var iterFn = iterable[std_iterator]; for (var nextItem of allowContentIter(iterable)) {
if (!IsCallable(iterFn))
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
var iter = callContentFunction(iterFn, iterable);
if (!IsObject(iter))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
// Step 7 (not applicable).
// Step 8.
while (true) {
// Step 8.a.
var next = callContentFunction(iter.next, iter);
if (!IsObject(next))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
// Step 8.b.
if (next.done)
return;
// Step 8.c.
var nextItem = next.value;
// Step 8.d. // Step 8.d.
if (!IsObject(nextItem)) { if (!IsObject(nextItem))
IteratorCloseThrow(iter);
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Map"); ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Map");
}
// Steps 8.e-j. // Steps 8.e-j.
try { callContentFunction(adder, map, nextItem[0], nextItem[1]);
callContentFunction(adder, map, nextItem[0], nextItem[1]);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
} }
} }

View file

@ -14,39 +14,9 @@ function SetConstructorInit(iterable) {
if (!IsCallable(adder)) if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder); ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c. // Steps 6.c-8.
var iterFn = iterable[std_iterator]; for (var nextValue of allowContentIter(iterable))
if (!IsCallable(iterFn)) callContentFunction(adder, set, nextValue);
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
var iter = callContentFunction(iterFn, iterable);
if (!IsObject(iter))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
// Step 7 (not applicable).
// Step 8.
while (true) {
// Step 8.a.
var next = callContentFunction(iter.next, iter);
if (!IsObject(next))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
// Step 8.b.
if (next.done)
return;
// Step 8.c.
var nextValue = next.value;
// Steps 8.d-e.
try {
callContentFunction(adder, set, nextValue);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
}
} }
/* ES6 20121122 draft 15.16.4.6. */ /* ES6 20121122 draft 15.16.4.6. */

View file

@ -154,29 +154,6 @@ function GetIterator(obj, method) {
return iterator; return iterator;
} }
// ES2017 draft rev 7.4.6.
// When completion.[[Type]] is throw.
function IteratorCloseThrow(iter) {
// Steps 1-2 (implicit)
// Step 3.
var returnMethod = GetMethod(iter, "return");
// Step 4 (done in caller).
if (returnMethod === undefined)
return;
try {
// Step 5.
callContentFunction(returnMethod, iter);
} catch (e) {
}
// Step 6 (done in caller).
// Steps 7-9 (skipped).
}
var _builtinCtorsCache = {__proto__: null}; var _builtinCtorsCache = {__proto__: null};
function GetBuiltinConstructor(builtinName) { function GetBuiltinConstructor(builtinName) {

View file

@ -14,43 +14,13 @@ function WeakMapConstructorInit(iterable) {
if (!IsCallable(adder)) if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder); ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c. // Steps 6.c-8.
var iterFn = iterable[std_iterator]; for (var nextItem of allowContentIter(iterable)) {
if (!IsCallable(iterFn))
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
var iter = callContentFunction(iterFn, iterable);
if (!IsObject(iter))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
// Step 7 (not applicable).
// Step 8.
while (true) {
// Step 8.a.
var next = callContentFunction(iter.next, iter);
if (!IsObject(next))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
// Step 8.b.
if (next.done)
return;
// Step 8.c.
var nextItem = next.value;
// Step 8.d. // Step 8.d.
if (!IsObject(nextItem)) { if (!IsObject(nextItem))
IteratorCloseThrow(iter);
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "WeakMap"); ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "WeakMap");
}
// Steps 8.e-j. // Steps 8.e-j.
try { callContentFunction(adder, map, nextItem[0], nextItem[1]);
callContentFunction(adder, map, nextItem[0], nextItem[1]);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
} }
} }

View file

@ -14,39 +14,9 @@ function WeakSetConstructorInit(iterable) {
if (!IsCallable(adder)) if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder); ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c. // Steps 6.c-8.
var iterFn = iterable[std_iterator]; for (var nextValue of allowContentIter(iterable))
if (!IsCallable(iterFn)) callContentFunction(adder, set, nextValue);
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
var iter = callContentFunction(iterFn, iterable);
if (!IsObject(iter))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
// Step 7 (not applicable).
// Step 8.
while (true) {
// Step 8.a.
var next = callContentFunction(iter.next, iter);
if (!IsObject(next))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
// Step 8.b.
if (next.done)
return;
// Step 8.c.
var nextValue = next.value;
// Steps 8.d-e.
try {
callContentFunction(adder, set, nextValue);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
}
} }
// 23.4.3.1 // 23.4.3.1