Replace makeIterator with inline definitions

This commit is contained in:
André Bargull 2025-04-30 14:15:39 +02:00 committed by Philip Chimento
parent e11da732b2
commit ae5a0f3626
5 changed files with 197 additions and 155 deletions

View File

@ -5,35 +5,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*--- /*---
defines: [makeIterator, assertThrowsValue, assertThrownErrorContains, assertThrowsInstanceOfWithMessageCheck, assertThrowsInstanceOf, assertThrowsInstanceOfWithMessage, assertThrowsInstanceOfWithMessageContains, assertDeepEq] defines: [assertThrowsValue, assertThrownErrorContains, assertThrowsInstanceOfWithMessageCheck, assertThrowsInstanceOf, assertThrowsInstanceOfWithMessage, assertThrowsInstanceOfWithMessageContains, assertDeepEq]
allow_unused: True allow_unused: True
---*/ ---*/
(function() { (function() {
const undefined = void 0; const undefined = void 0;
/** Make an iterator with a return method. */
globalThis.makeIterator = function makeIterator(overrides) {
var throwMethod;
if (overrides && overrides.throw)
throwMethod = overrides.throw;
var iterator = {
throw: throwMethod,
next: function(x) {
if (overrides && overrides.next)
return overrides.next(x);
return { done: false };
},
return: function(x) {
if (overrides && overrides.ret)
return overrides.ret(x);
return { done: true };
}
};
return function() { return iterator; };
};
if (typeof globalThis.assertThrowsValue === 'undefined') { if (typeof globalThis.assertThrowsValue === 'undefined') {
globalThis.assertThrowsValue = function assertThrowsValue(f, val, msg) { globalThis.assertThrowsValue = function assertThrowsValue(f, val, msg) {
var fullmsg; var fullmsg;

View File

@ -6,10 +6,9 @@ includes: [sm/non262.js, sm/non262-shell.js]
flags: flags:
- noStrict - noStrict
description: | description: |
pending Tests that IteratorClose is called in array destructuring patterns.
esid: pending esid: pending
---*/ ---*/
// Tests that IteratorClose is called in array destructuring patterns.
function test() { function test() {
var returnCalled = 0; var returnCalled = 0;
@ -17,24 +16,31 @@ function test() {
var iterable = {}; var iterable = {};
// empty [] calls IteratorClose regardless of "done" on the result. // empty [] calls IteratorClose regardless of "done" on the result.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
return { done: true }; next() {
}, return { done: true };
ret: function() { },
returnCalled++; return() {
return {}; returnCalled++;
} return {};
}); }
};
};
var [] = iterable; var [] = iterable;
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
return {}; return { done: false };
} },
}); return() {
returnCalled++;
return {};
}
};
};
var [] = iterable; var [] = iterable;
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
@ -55,43 +61,52 @@ function test() {
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// throw in lhs ref calls IteratorClose with falsy "done". // throw in lhs ref calls IteratorClose with falsy "done".
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
// "done" is undefined. next() {
return {}; // "done" is undefined.
}, return {};
ret: function() { },
returnCalled++; return() {
return {}; returnCalled++;
} return {};
}); }
};
};
assertThrowsValue(function() { assertThrowsValue(function() {
0, [...{}[throwlhs()]] = iterable; 0, [...{}[throwlhs()]] = iterable;
}, "in lhs"); }, "in lhs");
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// throw in iter.next doesn't call IteratorClose // throw in iter.next doesn't call IteratorClose
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
throw "in next"; next() {
}, throw "in next";
ret: function() { },
returnCalled++; return() {
return {}; returnCalled++;
} return {};
}); }
};
};
assertThrowsValue(function() { assertThrowsValue(function() {
var [d] = iterable; var [d] = iterable;
}, "in next"); }, "in next");
assert.sameValue(returnCalled, returnCalledExpected); assert.sameValue(returnCalled, returnCalledExpected);
// "return" must return an Object. // "return" must return an Object.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
return 42; return { done: false };
} },
}); return() {
returnCalled++;
return 42;
}
};
};
assertThrowsInstanceOf(function() { assertThrowsInstanceOf(function() {
var [] = iterable; var [] = iterable;
}, TypeError); }, TypeError);

View File

@ -20,16 +20,18 @@ function test() {
var throwCalled = 0; var throwCalled = 0;
var throwCalledExpected = 0; var throwCalledExpected = 0;
var iterable = {}; var iterable = {};
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
nextCalled++; next() {
return { done: false }; nextCalled++;
}, return { done: false };
ret: function() { },
returnCalled++; return() {
return { done: true, value: "iter.return" }; returnCalled++;
} return { done: true, value: "iter.return" };
}); }
};
};
function* y() { function* y() {
yield* iterable; yield* iterable;
@ -60,16 +62,18 @@ function test() {
// G.p.return calls "return", and if the result.done is false, continue // G.p.return calls "return", and if the result.done is false, continue
// yielding. // yielding.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
nextCalled++; next() {
return { done: false }; nextCalled++;
}, return { done: false };
ret: function() { },
returnCalled++; return() {
return { done: false, value: "iter.return" }; returnCalled++;
} return { done: false, value: "iter.return" };
}); }
};
};
var g3 = y(); var g3 = y();
g3.next(); g3.next();
var v3 = g3.return("test return"); var v3 = g3.return("test return");
@ -81,12 +85,17 @@ function test() {
assert.sameValue(nextCalled, ++nextCalledExpected); assert.sameValue(nextCalled, ++nextCalledExpected);
// G.p.return throwing does not re-call iter.return. // G.p.return throwing does not re-call iter.return.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
throw "in iter.return"; return { done: false };
} },
}); return() {
returnCalled++;
throw "in iter.return";
}
};
};
var g4 = y(); var g4 = y();
g4.next(); g4.next();
assertThrowsValue(function() { assertThrowsValue(function() {
@ -95,12 +104,17 @@ function test() {
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// G.p.return expects iter.return to return an Object. // G.p.return expects iter.return to return an Object.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
return 42; return { done: false };
} },
}); return() {
returnCalled++;
return 42;
}
};
};
var g5 = y(); var g5 = y();
g5.next(); g5.next();
assertThrowsInstanceOf(function() { assertThrowsInstanceOf(function() {
@ -119,29 +133,39 @@ function test() {
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// G.p.return passes its argument to "return". // G.p.return passes its argument to "return".
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function(x) { return {
assert.sameValue(x, "in test"); next() {
returnCalled++; return { done: false };
return { done: true }; },
} return(x) {
}); assert.sameValue(x, "in test");
returnCalled++;
return { done: true };
}
};
};
var g7 = y(); var g7 = y();
g7.next(); g7.next();
g7.return("in test"); g7.return("in test");
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// If a throw method is present, do not call "return". // If a throw method is present, do not call "return".
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
throw: function(e) { return {
throwCalled++; next() {
throw e; return { done: false };
}, },
ret: function(x) { throw(e) {
returnCalled++; throwCalled++;
return { done: true }; throw e;
} },
}); return() {
returnCalled++;
return { done: true };
}
};
};
var g8 = y(); var g8 = y();
g8.next(); g8.next();
assertThrowsValue(function() { assertThrowsValue(function() {

View File

@ -16,12 +16,17 @@ function test() {
var finallyEntered = 0; var finallyEntered = 0;
var finallyEnteredExpected = 0; var finallyEnteredExpected = 0;
var iterable = {}; var iterable = {};
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
throw 42; return { done: false };
} },
}); return() {
returnCalled++;
throw 42;
}
};
};
// inner try cannot catch IteratorClose throwing // inner try cannot catch IteratorClose throwing
assertThrowsValue(function() { assertThrowsValue(function() {

View File

@ -6,22 +6,25 @@ includes: [sm/non262.js, sm/non262-shell.js]
flags: flags:
- noStrict - noStrict
description: | description: |
pending Tests that IteratorReturn is called when a for-of loop has an abrupt completion value during non-iterator code.
esid: pending esid: pending
---*/ ---*/
// Tests that IteratorReturn is called when a for-of loop has an abrupt
// completion value during non-iterator code.
function test() { function test() {
var returnCalled = 0; var returnCalled = 0;
var returnCalledExpected = 0; var returnCalledExpected = 0;
var iterable = {}; var iterable = {};
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
return {}; return { done: false };
} },
}); return() {
returnCalled++;
return {};
}
};
};
// break calls iter.return // break calls iter.return
for (var x of iterable) for (var x of iterable)
@ -46,12 +49,17 @@ function test() {
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// throw in iter.return doesn't re-call iter.return // throw in iter.return doesn't re-call iter.return
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
throw "in iter.return"; return { done: false };
} },
}); return() {
returnCalled++;
throw "in iter.return";
}
};
};
assertThrowsValue(function() { assertThrowsValue(function() {
for (var x of iterable) for (var x of iterable)
break; break;
@ -59,11 +67,16 @@ function test() {
assert.sameValue(returnCalled, ++returnCalledExpected); assert.sameValue(returnCalled, ++returnCalledExpected);
// throw in iter.next doesn't call IteratorClose // throw in iter.next doesn't call IteratorClose
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
throw "in next"; next() {
} throw "in next";
}); },
return() {
return { done: true };
}
};
};
assertThrowsValue(function() { assertThrowsValue(function() {
for (var x of iterable) for (var x of iterable)
break; break;
@ -71,12 +84,17 @@ function test() {
assert.sameValue(returnCalled, returnCalledExpected); assert.sameValue(returnCalled, returnCalledExpected);
// "return" must return an Object. // "return" must return an Object.
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
ret: function() { return {
returnCalled++; next() {
return 42; return { done: false };
} },
}); return() {
returnCalled++;
return 42;
}
};
};
assertThrowsInstanceOf(function() { assertThrowsInstanceOf(function() {
for (var x of iterable) for (var x of iterable)
break; break;
@ -85,15 +103,17 @@ function test() {
// continue doesn't call iter.return for the loop it's continuing // continue doesn't call iter.return for the loop it's continuing
var i = 0; var i = 0;
iterable[Symbol.iterator] = makeIterator({ iterable[Symbol.iterator] = function() {
next: function() { return {
return { done: i++ > 5 }; next() {
}, return { done: i++ > 5 };
ret: function() { },
returnCalled++; return() {
return {}; returnCalled++;
} return {};
}); }
};
};
for (var x of iterable) for (var x of iterable)
continue; continue;
assert.sameValue(returnCalled, returnCalledExpected); assert.sameValue(returnCalled, returnCalledExpected);