lib: add Iterator global to primordials, improve iteration object coverage in frozen intrinsics#63698
lib: add Iterator global to primordials, improve iteration object coverage in frozen intrinsics#63698Renegade334 wants to merge 2 commits into
Conversation
187e6c7 to
51aa657
Compare
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
51aa657 to
00e4207
Compare
It's a spec fiction used for defining behavior of other algorithms (for-await over a sync iterator, specifically), not a real thing (although engines might choose to have an internal representation of it for ease of implementation). |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #63698 +/- ##
==========================================
- Coverage 91.96% 90.35% -1.61%
==========================================
Files 379 732 +353
Lines 166638 236691 +70053
Branches 25497 44583 +19086
==========================================
+ Hits 153242 213867 +60625
- Misses 13099 14563 +1464
- Partials 297 8261 +7964
🚀 New features to boost your workflow:
|
This comment has been minimized.
This comment has been minimized.
| [ | ||
| { | ||
| name: 'ArrayIteratorPrototype', | ||
| original: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()), | ||
| }, | ||
| { | ||
| name: 'AsyncIteratorPrototype', | ||
| original: Reflect.getPrototypeOf(Reflect.getPrototypeOf(async function*() {}).prototype), | ||
| }, | ||
| { | ||
| name: 'StringIteratorPrototype', | ||
| original: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()), | ||
| }, | ||
| ].forEach(({ name, original }) => { |
There was a problem hiding this comment.
We might as well put them all into primordials since we're using them. wdyt about droping the repeating Prototype since this whole section is prototype-only as reminded by the comment you added?
| [ | |
| { | |
| name: 'ArrayIteratorPrototype', | |
| original: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()), | |
| }, | |
| { | |
| name: 'AsyncIteratorPrototype', | |
| original: Reflect.getPrototypeOf(Reflect.getPrototypeOf(async function*() {}).prototype), | |
| }, | |
| { | |
| name: 'StringIteratorPrototype', | |
| original: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()), | |
| }, | |
| ].forEach(({ name, original }) => { | |
| Object.entries({ | |
| ArrayIterator: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()), | |
| AsyncFunction: Reflect.getPrototypeOf(async function() {}), | |
| AsyncGeneratorFunction: Reflect.getPrototypeOf(async function*() {}), | |
| AsyncIterator: Reflect.getPrototypeOf(Reflect.getPrototypeOf(async function*() {}).prototype), | |
| GeneratorFunction: Reflect.getPrototypeOf(function*() {}), | |
| IteratorHelper: Reflect.getPrototypeOf(primordials.IteratorPrototypeDrop({ __proto__: null }, null)), | |
| MapIterator: Reflect.getPrototypeOf(new primordials.Map()[Symbol.iterator]()), | |
| // eslint-disable-next-line regexp/no-empty-group | |
| RegExpStringIterator: Reflect.getPrototypeOf(/(?:)/[Symbol.matchAll]()), | |
| SetIterator: Reflect.getPrototypeOf(new primordials.Set()[Symbol.iterator]()), | |
| StringIterator: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()), | |
| WrapForValidIterator: Reflect.getPrototypeOf(primordials.IteratorFrom({ __proto__: null })), | |
| }).forEach(({ 0: name, 1: original }) => { | |
| name += 'Prototype'; |
There was a problem hiding this comment.
If we take that suggestion, we should also avoid re-generating the uncurried next function for SafeMapIterator and SafeSetIterator
diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js
index 6598db037e1..ec9e8c8af6d 100644
--- a/lib/internal/per_context/primordials.js
+++ b/lib/internal/per_context/primordials.js
@@ -379,10 +379,9 @@ const copyProps = (src, dest) => {
/**
* @type {typeof primordials.makeSafe}
*/
-const makeSafe = (unsafe, safe) => {
+const makeSafe = (unsafe, safe, next) => {
if (SymbolIterator in unsafe.prototype) {
const dummy = new unsafe();
- let next; // We can reuse the same `next` method.
ArrayPrototypeForEach(ReflectOwnKeys(unsafe.prototype), (key) => {
if (!ReflectGetOwnPropertyDescriptor(safe.prototype, key)) {
@@ -419,6 +418,7 @@ primordials.makeSafe = makeSafe;
primordials.SafeMap = makeSafe(
Map,
class SafeMap extends Map {},
+ primordials.MapIteratorPrototypeNext,
);
primordials.SafeWeakMap = makeSafe(
WeakMap,
@@ -428,6 +428,7 @@ primordials.SafeWeakMap = makeSafe(
primordials.SafeSet = makeSafe(
Set,
class SafeSet extends Set {},
+ primordials.SetIteratorPrototypeNext,
);
primordials.SafeWeakSet = makeSafe(
WeakSet,
lib: add Iterator global to primordials
iterator_helpers is unflagged in V8 from v24.x.
lib: improve control abstraction coverage in frozen intrinsics
Adds the new internal iteration prototypes (
%IteratorHelperPrototype%,%WrapForValidIteratorPrototype%) to frozen intrinsics, and improves/deduplicates coverage of iterator/generator objects.Note that
%AsyncFromSyncIteratorPrototype%is missing from the iterator spec – this is unresolvable AFAICT.