diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-03-25 12:56:18 +0200 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-03-25 12:56:18 +0200 |
commit | e641a2c53a857141042ca62f1fe0b63b55a130af (patch) | |
tree | 63a6c5dc142a1be2ae75cb4cfa3871a8c4801d38 | |
parent | 34533e06a7b6f73bb9cf16058207e97bd91c832c (diff) | |
download | uxp-e641a2c53a857141042ca62f1fe0b63b55a130af.tar.gz |
Bug 1334799 - Handle stack value in correct order when leaving for-of loop from finally block
Issue #74
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 6 | ||||
-rw-r--r-- | js/src/tests/ecma_6/Statements/for-inof-finally.js | 32 |
2 files changed, 31 insertions, 7 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index bf7797d376..76f1f75b5e 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2396,6 +2396,9 @@ NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* ta } } + if (!flushPops(bce_)) + return false; + if (target && target->is<ForOfLoopControl>() && emitIteratorCloseAtTarget) { hasForOfLoopsWithIteratorClose = true; if (!target->as<ForOfLoopControl>().finishIterCloseTryNote(bce_)) @@ -2417,9 +2420,6 @@ NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* ta return false; } - if (!flushPops(bce_)) - return false; - // See comment in ForOfLoopControl. if (hasForOfLoopsWithIteratorClose) { for (NestableControl* control = bce_->innermostNestableControl; diff --git a/js/src/tests/ecma_6/Statements/for-inof-finally.js b/js/src/tests/ecma_6/Statements/for-inof-finally.js index 187dcdaf5f..e1f0c77e12 100644 --- a/js/src/tests/ecma_6/Statements/for-inof-finally.js +++ b/js/src/tests/ecma_6/Statements/for-inof-finally.js @@ -4,6 +4,24 @@ var summary = print(BUGNUMBER + ": " + summary); +var called = 0; +function reset() { + called = 0; +} +var obj = { + [Symbol.iterator]() { + return { + next() { + return { value: 10, done: false }; + }, + return() { + called++; + return {}; + } + }; + } +}; + var a = (function () { for (var x in [0]) { try {} finally { @@ -13,32 +31,37 @@ var a = (function () { })(); assertEq(a, 11); +reset(); var b = (function () { - for (var x of [0]) { + for (var x of obj) { try {} finally { return 12; } } })(); +assertEq(called, 1); assertEq(b, 12); +reset(); var c = (function () { for (var x in [0]) { - for (var y of [0]) { + for (var y of obj) { try {} finally { return 13; } } } })(); +assertEq(called, 1); assertEq(c, 13); +reset(); var d = (function () { for (var x in [0]) { - for (var y of [0]) { + for (var y of obj) { try {} finally { for (var z in [0]) { - for (var w of [0]) { + for (var w of obj) { try {} finally { return 14; } @@ -48,6 +71,7 @@ var d = (function () { } } })(); +assertEq(called, 2); assertEq(d, 14); if (typeof reportCompare === "function") |