diff options
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 6 | ||||
-rw-r--r-- | js/src/tests/ecma_6/Statements/for-inof-finally.js | 54 |
2 files changed, 60 insertions, 0 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 98679eac6..bf7797d37 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2359,6 +2359,9 @@ NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* ta } case StatementKind::ForOfLoop: + if (!flushPops(bce_)) + return false; + // The iterator and the current value are on the stack. // if (emitIteratorClose) { @@ -2378,6 +2381,9 @@ NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* ta break; case StatementKind::ForInLoop: + if (!flushPops(bce_)) + return false; + // The iterator and the current value are on the stack. if (!bce_->emit1(JSOP_POP)) // ... ITER return false; diff --git a/js/src/tests/ecma_6/Statements/for-inof-finally.js b/js/src/tests/ecma_6/Statements/for-inof-finally.js new file mode 100644 index 000000000..187dcdaf5 --- /dev/null +++ b/js/src/tests/ecma_6/Statements/for-inof-finally.js @@ -0,0 +1,54 @@ +var BUGNUMBER = 1332881; +var summary = + "Leaving for-in and try should handle stack value in correct order"; + +print(BUGNUMBER + ": " + summary); + +var a = (function () { + for (var x in [0]) { + try {} finally { + return 11; + } + } +})(); +assertEq(a, 11); + +var b = (function () { + for (var x of [0]) { + try {} finally { + return 12; + } + } +})(); +assertEq(b, 12); + +var c = (function () { + for (var x in [0]) { + for (var y of [0]) { + try {} finally { + return 13; + } + } + } +})(); +assertEq(c, 13); + +var d = (function () { + for (var x in [0]) { + for (var y of [0]) { + try {} finally { + for (var z in [0]) { + for (var w of [0]) { + try {} finally { + return 14; + } + } + } + } + } + } +})(); +assertEq(d, 14); + +if (typeof reportCompare === "function") + reportCompare(true, true); |