diff --git a/app/astride/sandbox.js b/app/astride/sandbox.js index cc14683..8e39a62 100644 --- a/app/astride/sandbox.js +++ b/app/astride/sandbox.js @@ -38,6 +38,7 @@ export default class Sandbox { if ( 'BlockStatement' === node.type || 'ForStatement' === node.type + || 'ForOfStatement' === node.type ) { switch (verb) { case 'enter': { @@ -325,14 +326,17 @@ export default class Sandbox { } scope.allocate('@@iterator', right.value[Symbol.iterator]()); } - if (this.$$execution.stack[depth + 1] === node) { - this.$$execution.stack.pop(); - } result = this.$$execution.deferred.get(node.body) || { value: undefined, yield: YIELD_NONE, }; - const {done, value} = scope.get('@@iterator').next(); + if (shouldVisitChild(node)) { + this.$$execution.deferred.set(node.left, scope.get('@@iterator').next()); + } + if (this.$$execution.stack[depth + 1] === node) { + this.$$execution.stack.pop(); + } + const {done, value} = this.$$execution.deferred.get(node.left); if (done) { this.$$execution.deferred.delete(node.body); break; diff --git a/app/astride/sandbox.test.js b/app/astride/sandbox.test.js index 59c1fdd..2622561 100644 --- a/app/astride/sandbox.test.js +++ b/app/astride/sandbox.test.js @@ -536,4 +536,20 @@ test('implements for...of', async () => { )).run() ) .to.deep.include({value: [2, 12, 30]}); + context.iterable = [{x: [[1, 2], [3, 4], [5, 6]]}]; + expect( + (new Sandbox( + await parse(` + const mapped = []; + for (const {x} of iterable) { + for (const [y, z] of x) { + mapped.push(y * z); + } + } + mapped + `), + context, + )).run() + ) + .to.deep.include({value: [2, 12, 30]}); });