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/. */
/*---
defines: [makeIterator, assertThrowsValue, assertThrownErrorContains, assertThrowsInstanceOfWithMessageCheck, assertThrowsInstanceOf, assertThrowsInstanceOfWithMessage, assertThrowsInstanceOfWithMessageContains, assertDeepEq]
defines: [assertThrowsValue, assertThrownErrorContains, assertThrowsInstanceOfWithMessageCheck, assertThrowsInstanceOf, assertThrowsInstanceOfWithMessage, assertThrowsInstanceOfWithMessageContains, assertDeepEq]
allow_unused: True
---*/
(function() {
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') {
globalThis.assertThrowsValue = function assertThrowsValue(f, val, msg) {
var fullmsg;

View File

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

View File

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

View File

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

View File

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