iterator-destructuring-property-reference-target-evaluation-order.js (2169B)
1 // Copyright (C) 2017 André Bargull. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 4 /*--- 5 esid: sec-runtime-semantics-iteratordestructuringassignmentevaluation 6 description: > 7 Ensure correct evaluation order when destructuring target is property reference. 8 info: | 9 12.15.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation 10 11 AssignmentElement : DestructuringAssignmentTarget Initializer 12 13 1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then 14 a. Let lref be the result of evaluating DestructuringAssignmentTarget. 15 b. ReturnIfAbrupt(lref). 16 2. If iteratorRecord.[[Done]] is false, then 17 a. Let next be IteratorStep(iteratorRecord.[[Iterator]]). 18 ... 19 3. If iteratorRecord.[[Done]] is true, let value be undefined. 20 ... 21 5. Else, let v be value. 22 ... 23 8. Return ? PutValue(lref, v). 24 features: [Symbol.iterator] 25 includes: [compareArray.js] 26 ---*/ 27 28 29 var log = []; 30 31 function source() { 32 log.push("source"); 33 var iterator = { 34 next: function() { 35 log.push("iterator-step"); 36 return { 37 get done() { 38 log.push("iterator-done"); 39 return true; 40 }, 41 get value() { 42 // Note: This getter shouldn't be called. 43 log.push("iterator-value"); 44 } 45 }; 46 } 47 }; 48 var source = {}; 49 source[Symbol.iterator] = function() { 50 log.push("iterator"); 51 return iterator; 52 }; 53 return source; 54 } 55 function target() { 56 log.push("target"); 57 return target = { 58 set q(v) { 59 log.push("set"); 60 } 61 }; 62 } 63 function targetKey() { 64 log.push("target-key"); 65 return { 66 toString: function() { 67 log.push("target-key-tostring"); 68 return "q"; 69 } 70 }; 71 } 72 73 ([target()[targetKey()]] = source()); 74 75 assert.compareArray(log, [ 76 "source", "iterator", 77 "target", "target-key", 78 "iterator-step", "iterator-done", 79 "target-key-tostring", "set", 80 ]); 81 82 reportCompare(0, 0);