Bug 835449 - fix StackIter corner case where evalInFrame fails to pop native calls (r=jandem)
authorLuke Wagner <luke@mozilla.com>
Mon, 28 Jan 2013 10:53:49 -0800
changeset 120237 456d199b8d1fc061407bc1e75d9920de8e8c3e83
parent 120236 f8b0ebdfe845f2195159c281e88c82d69c13ca38
child 120238 a16bd9c186009054b07ec7b41095f6c0f9965fae
push id24243
push userryanvm@gmail.com
push dateWed, 30 Jan 2013 00:49:21 +0000
treeherdermozilla-central@5c248ef0fe62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs835449
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 835449 - fix StackIter corner case where evalInFrame fails to pop native calls (r=jandem)
js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js
js/src/vm/Stack.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js
@@ -0,0 +1,11 @@
+// |jit-test| debug
+
+function g() {
+    var x = 100;
+    return evalInFrame(2, "x");
+}
+function f() {
+    var x = 42;
+    return evalInFrame.call(null, 0, "g()");
+}
+assertEq(f.call(), 42);
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1368,17 +1368,19 @@ StackIter::settleOnNewState()
         bool containsCall = data_.seg_->contains(data_.calls_);
         while (!containsFrame && !containsCall) {
             /* Eval-in-frame can cross contexts, so use prevInMemory. */
             data_.seg_ = data_.seg_->prevInMemory();
             containsFrame = data_.seg_->contains(data_.fp_);
             containsCall = data_.seg_->contains(data_.calls_);
 
             /* Eval-in-frame allows jumping into the middle of a segment. */
-            if (containsFrame && data_.seg_->fp() != data_.fp_) {
+            if (containsFrame &&
+                (data_.seg_->fp() != data_.fp_ || data_.seg_->maybeCalls() != data_.calls_))
+            {
                 /* Avoid duplicating logic; seg_ contains fp_, so no iloop. */
                 StackIter tmp = *this;
                 tmp.startOnSegment(data_.seg_);
                 while (!tmp.isScript() || tmp.data_.fp_ != data_.fp_)
                     ++tmp;
                 JS_ASSERT(tmp.isScript() &&
                           tmp.data_.seg_ == data_.seg_ &&
                           tmp.data_.fp_ == data_.fp_);