mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 924040 - Update yield* to use @@iterator protocol. r=jwalden
This commit is contained in:
parent
c7fe19aa1f
commit
5dc7836409
@ -5109,9 +5109,22 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
|
||||
JS_ASSERT(bce->sc->isFunctionBox());
|
||||
JS_ASSERT(bce->sc->asFunctionBox()->isStarGenerator());
|
||||
|
||||
if (!EmitTree(cx, bce, iter)) // ITER
|
||||
if (!EmitTree(cx, bce, iter)) // ITERABLE
|
||||
return false;
|
||||
|
||||
// Convert iterable to iterator.
|
||||
if (Emit1(cx, bce, JSOP_DUP) < 0) // ITERABLE ITERABLE
|
||||
return false;
|
||||
if (!EmitAtomOp(cx, cx->names().std_iterator, JSOP_CALLPROP, bce)) // ITERABLE @@ITERATOR
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_SWAP) < 0) // @@ITERATOR ITERABLE
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_NOTEARG) < 0)
|
||||
return false;
|
||||
if (EmitCall(cx, bce, JSOP_CALL, 0) < 0) // ITER
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_CALL);
|
||||
|
||||
int depth = bce->stackDepth;
|
||||
JS_ASSERT(depth >= 1);
|
||||
|
||||
|
@ -10,16 +10,20 @@ function results(results) {
|
||||
function next() {
|
||||
return results[i++];
|
||||
}
|
||||
return { next: next }
|
||||
var iter = { next: next }
|
||||
var ret = {};
|
||||
ret[std_iterator] = function () { return iter; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
function* yield_results(expected) {
|
||||
return yield* results(expected);
|
||||
}
|
||||
|
||||
function collect_results(iter) {
|
||||
function collect_results(iterable) {
|
||||
var ret = [];
|
||||
var result;
|
||||
var iter = iterable[std_iterator]();
|
||||
do {
|
||||
result = iter.next();
|
||||
ret.push(result);
|
||||
|
@ -8,6 +8,7 @@ function Iter() {
|
||||
}
|
||||
|
||||
this.next = next;
|
||||
this[std_iterator] = function () { return this; }
|
||||
}
|
||||
|
||||
function* delegate(iter) { return yield* iter; }
|
||||
|
49
js/src/tests/ecma_6/Generators/delegating-yield-12.js
Normal file
49
js/src/tests/ecma_6/Generators/delegating-yield-12.js
Normal file
@ -0,0 +1,49 @@
|
||||
// yield* calls @@iterator on the iterable to produce the iterator.
|
||||
|
||||
var log = '';
|
||||
|
||||
function IteratorWrapper(iterator) {
|
||||
return {
|
||||
next: function (val) {
|
||||
log += 'n';
|
||||
return iterator.next(val);
|
||||
},
|
||||
|
||||
throw: function (exn) {
|
||||
log += 't';
|
||||
return iterator.throw(exn);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function IterableWrapper(iterable) {
|
||||
var ret = {};
|
||||
|
||||
ret[std_iterator] = function () {
|
||||
log += 'i';
|
||||
return IteratorWrapper(iterable[std_iterator]());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function* delegate(iter) { return yield* iter; }
|
||||
|
||||
var iter = delegate(IterableWrapper([1, 2, 3]));
|
||||
assertIteratorResult(1, false, iter.next());
|
||||
assertIteratorResult(2, false, iter.next());
|
||||
assertIteratorResult(3, false, iter.next());
|
||||
assertIteratorResult(undefined, true, iter.next());
|
||||
|
||||
assertEq(log, 'innnn');
|
||||
|
||||
iter = delegate([1, 2, 3]);
|
||||
assertIteratorResult(1, false, iter.next());
|
||||
assertIteratorResult(2, false, iter.next());
|
||||
assertIteratorResult(3, false, iter.next());
|
||||
assertIteratorResult(undefined, true, iter.next());
|
||||
|
||||
assertEq(log, 'innnn');
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(true, true);
|
@ -6,16 +6,20 @@ function results(results) {
|
||||
function next() {
|
||||
return results[i++];
|
||||
}
|
||||
return { next: next }
|
||||
var iter = { next: next };
|
||||
var ret = {};
|
||||
ret[std_iterator] = function () { return iter; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
function* yield_results(expected, n) {
|
||||
return yield* n ? yield_results(expected, n - 1) : results(expected);
|
||||
}
|
||||
|
||||
function collect_results(iter) {
|
||||
function collect_results(iterable) {
|
||||
var ret = [];
|
||||
var result;
|
||||
var iter = iterable[std_iterator]();
|
||||
do {
|
||||
result = iter.next();
|
||||
ret.push(result);
|
||||
|
@ -15,13 +15,20 @@ function collect_results(iter) {
|
||||
|
||||
function Iter(val, count) {
|
||||
function next() {
|
||||
log += 'n';
|
||||
return {
|
||||
get done() { log += "d"; return count-- == 0; },
|
||||
get value() { log += "v"; return val; }
|
||||
}
|
||||
}
|
||||
|
||||
function iterator() {
|
||||
log += 'i';
|
||||
return this;
|
||||
}
|
||||
|
||||
this.next = next;
|
||||
this[std_iterator] = iterator;
|
||||
}
|
||||
|
||||
function* delegate(iter) { return yield* iter; }
|
||||
@ -37,13 +44,13 @@ outer.next();
|
||||
outer.next();
|
||||
outer.next();
|
||||
|
||||
assertEq(log, "ddddddv");
|
||||
assertEq(log, "indndndndndndv");
|
||||
|
||||
// Outer's dead, man. Outer's dead.
|
||||
assertThrowsInstanceOf(outer.next.bind(outer), TypeError);
|
||||
|
||||
// No more checking the iterator.
|
||||
assertEq(log, "ddddddv");
|
||||
assertEq(log, "indndndndndndv");
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(true, true);
|
||||
|
@ -2,10 +2,15 @@
|
||||
|
||||
function results(results) {
|
||||
var i = 0;
|
||||
function iterator() {
|
||||
return this;
|
||||
}
|
||||
function next() {
|
||||
return results[i++];
|
||||
}
|
||||
return { next: next }
|
||||
var ret = { next: next }
|
||||
ret[std_iterator] = iterator;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function* yield_results(expected) {
|
||||
|
@ -3,9 +3,20 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var std_iterator = (function() {
|
||||
try {
|
||||
for (var _ of new Proxy({}, { get: function(_, name) { throw name; } }))
|
||||
break;
|
||||
} catch (name) {
|
||||
return name;
|
||||
}
|
||||
throw 'wat';
|
||||
})();
|
||||
|
||||
function assertFalse(a) { assertEq(a, false) }
|
||||
function assertTrue(a) { assertEq(a, true) }
|
||||
function assertNotEq(found, not_expected) { assertFalse(found === expected) }
|
||||
function assertIteratorResult(value, done, result) {
|
||||
assertDeepEq(result, { value: value, done: done });
|
||||
assertDeepEq(result.value, value);
|
||||
assertEq(result.done, done);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user