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.
var A = IsConstructor(C) ? new C() : [];
// Step 5.c.
var iterator = GetIterator(items, usingIterator);
// Step 5.d.
var k = 0;
// 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) {
// Step 5.c, 5.e.
var iteratorWrapper = { [std_iterator]() { return GetIterator(items, usingIterator); } };
for (var nextValue of allowContentIter(iteratorWrapper)) {
// 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);
if (k >= 0x1fffffffffffff)
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.
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.
_DefineDataProperty(A, k++, mappedValue);
} catch (e) {
// Steps 5.e.vi.2, 5.e.ix.
IteratorCloseThrow(iterator);
throw e;
}
// Steps 5.e.ii (reordered), 5.e.viii.
_DefineDataProperty(A, k++, mappedValue);
}
// Step 5.e.iv.
A.length = k;
return A;
}
// Step 7.

View file

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

View file

@ -14,44 +14,14 @@ function MapConstructorInit(iterable) {
if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c.
var iterFn = iterable[std_iterator];
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;
// Steps 6.c-8.
for (var nextItem of allowContentIter(iterable)) {
// Step 8.d.
if (!IsObject(nextItem)) {
IteratorCloseThrow(iter);
if (!IsObject(nextItem))
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Map");
}
// Steps 8.e-j.
try {
callContentFunction(adder, map, nextItem[0], nextItem[1]);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
callContentFunction(adder, map, nextItem[0], nextItem[1]);
}
}

View file

@ -14,39 +14,9 @@ function SetConstructorInit(iterable) {
if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c.
var iterFn = iterable[std_iterator];
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 nextValue = next.value;
// Steps 8.d-e.
try {
callContentFunction(adder, set, nextValue);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
}
// Steps 6.c-8.
for (var nextValue of allowContentIter(iterable))
callContentFunction(adder, set, nextValue);
}
/* ES6 20121122 draft 15.16.4.6. */

View file

@ -154,29 +154,6 @@ function GetIterator(obj, method) {
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};
function GetBuiltinConstructor(builtinName) {

View file

@ -14,43 +14,13 @@ function WeakMapConstructorInit(iterable) {
if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c.
var iterFn = iterable[std_iterator];
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;
// Steps 6.c-8.
for (var nextItem of allowContentIter(iterable)) {
// Step 8.d.
if (!IsObject(nextItem)) {
IteratorCloseThrow(iter);
if (!IsObject(nextItem))
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "WeakMap");
}
// Steps 8.e-j.
try {
callContentFunction(adder, map, nextItem[0], nextItem[1]);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
callContentFunction(adder, map, nextItem[0], nextItem[1]);
}
}

View file

@ -14,39 +14,9 @@ function WeakSetConstructorInit(iterable) {
if (!IsCallable(adder))
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
// Step 6.c.
var iterFn = iterable[std_iterator];
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 nextValue = next.value;
// Steps 8.d-e.
try {
callContentFunction(adder, set, nextValue);
} catch (e) {
IteratorCloseThrow(iter);
throw e;
}
}
// Steps 6.c-8.
for (var nextValue of allowContentIter(iterable))
callContentFunction(adder, set, nextValue);
}
// 23.4.3.1