for-in loop: if iterator.next() returns {done: true}, with no .value property, iteration does not stop (with Proxy enumerate trap)

RESOLVED DUPLICATE of bug 1246318

Status

()

defect
RESOLVED DUPLICATE of bug 1246318
4 years ago
3 years ago

People

(Reporter: leonardo.balter, Unassigned)

Tracking

(Blocks 1 bug)

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

4 years ago
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0
Build ID: 20150630154324

Steps to reproduce:

```
var x;
var p = new Proxy([1,2,3], {
    enumerate: function() {
        return { next: function() { return { done:true }; } };
    }
});

for (x in p) {
    $ERROR("returned iterable interface from trap is flagged as done.");
}
```

this is a current valid test from the test262 project: https://github.com/tc39/test262/blob/master/test/built-ins/Proxy/enumerate/return-trap-result-no-value.js

Related to Proxy enumerate 9.5.11 from the ES6 spec.



Actual results:

It iterates on the for .. in loop, when the Proxy handler returns a closed ({done: true}) iterator. 


Expected results:

The enumerate trap returns a closed iterator, and the for .. in block shouldn't loop on it.

```
    enumerate: function() {
        return { next: function() { return { done:true }; } };
    }
```
The problem here, I assume, is that js::IteratorMore has:

1341     // If the object has both the done and value property, we assume
1342     // it's using the new style protocol. Otherwise just return the object.

And indeed, if I add "value: undefined" to that object that next() returns I get the expected behavior.

There are also comments about "old style generators" and "we try to support the old and new iterator protocol at the same time!" in that code.

Jason, do you know what the plan is for removing the old style iterator protocol?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(jorendorff)
Summary: iterates after Proxy enumerate trap returning a done iterator iterface → iterates after Proxy enumerate trap returning a done iterator iterface with no "value" property
I had opened bug 1112564 to do this, after we at least remove __iterator__ and change Iterator().
Blocks: es6
Flags: needinfo?(jorendorff)
If we can remove __iterator__ right now, great.

If not, we could change iteration
so that any code in the engine that calls __iterator__
assumes that it's going to return an old-style iterator
and wraps it in an adapter object that's an ES6 iterator.

That way IteratorMore can drop support for old-style iterators.
Summary: iterates after Proxy enumerate trap returning a done iterator iterface with no "value" property → for-in loop: if iterator.next() returns {done: true}, with no .value property, iteration does not stop (with Proxy enumerate trap)
Status: NEW → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1246318
You need to log in before you can comment on or make changes to this bug.