Currently, |for (V in EXPR) STMT| compiles to bytecode like this: EXPR iter 1 goto L2 L1: trace iternext 2 setlocal V ;; or other set instruction(s) pop STMT L2: moreiter ifne L1 enditer There is duplication of work between moreiter and iternext. This means at least one extra conditional branch (guarding the iterator class). To eliminate that, there should be a single instruction that computes the new value and puts it on the stack. There are two ways to do it. Option 1: Keep JSOP_ITERNEXT, turning it into a conditional branch, and eliminate JSOP_ITERMORE. The bytecode would look like this: EXPR iter 1 L1: trace iternext L2 setlocal V ;; or other set instruction(s) pop STMT goto L1 L2: enditer Destructuring cases require a JSOP_PICK, but it isn't that bad. Option 2: Keep moreiter and remove nextiter: EXPR iter 1 push goto L2 L1: trace setlocal V ;; or other set instruction(s) pop STMT push L2: moreiter ifne L1 enditer I think those JSOP_PUSH opcodes are necessary because my understanding is that the operand stack depth must be unchanged from a JSOP_GOTO to the subsequent instruction, even though control can't flow that way. I like option 1.
This is what i thought of, too. Option 1++
BTW, a perk of changing this: we can remove JSContext::iterValue.
Summary: Fuse js_IteratorMore with js_IteratorNext and remove the JSOP_ITERMORE opcode → Fuse js_IteratorMore with js_IteratorNext and remove the JSOP_MOREITER opcode
Stealing. I think I want the code to look like this: EXPR obj enterfor 1 L2 iter L1: setlocal V iter val pop iter STMT iter L2: next L1 iter val leavefor The operand stack depth thing is a silly constraint; I'll push through that.
Assignee: evilpies → jorendorff
Untaking again. Can't get around to it.
Assignee: jorendorff → general
Status: NEW → RESOLVED
Last Resolved: 6 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 777596
You need to log in before you can comment on or make changes to this bug.