star-iterable-throw-emulates-undefined-throws-when-called.js (1600B)
1 // Copyright (C) 2020 Alexey Shvayka. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 /*--- 4 esid: sec-generator-function-definitions-runtime-semantics-evaluation 5 description: > 6 If <iterator>.throw is an object emulating `undefined` (e.g. `document.all` 7 in browsers), it shouldn't be treated as if it were actually `undefined` by 8 the yield* operator. 9 info: | 10 YieldExpression : yield * AssignmentExpression 11 12 [...] 13 7. Repeat, 14 [...] 15 b. Else if received.[[Type]] is throw, then 16 i. Let throw be ? GetMethod(iterator, "throw"). 17 ii. If throw is not undefined, then 18 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »). 19 [...] 20 4. If Type(innerResult) is not Object, throw a TypeError exception. 21 features: [generators, IsHTMLDDA] 22 ---*/ 23 24 var IsHTMLDDA = $262.IsHTMLDDA; 25 var returnCalls = 0; 26 var inner = { 27 [Symbol.iterator]() { return this; }, 28 next() { return {done: false}; }, 29 throw: IsHTMLDDA, 30 return() { 31 returnCalls += 1; 32 return {done: true}; 33 }, 34 }; 35 36 var outer = (function* () { yield* inner; })(); 37 outer.next(); 38 39 assert.throws(TypeError, function() { 40 // `IsHTMLDDA` is called here with `iter` as `this` and `emptyString` as the 41 // sole argument, and it's specified to return `null` under these conditions. 42 // As `iter`'s iteration isn't ending because of a throw, the iteration 43 // protocol will then throw a `TypeError` because `null` isn't an object. 44 var emptyString = ""; 45 outer.throw(emptyString); 46 }); 47 48 assert.sameValue(returnCalls, 0); 49 50 reportCompare(0, 0);