Bug 1303118 - Fix 'this' computation for Debugger.Frame.evalWithBindings. (r=efaust)
☠☠ backed out by dcebf2b98e14 ☠ ☠
authorShu-yu Guo <shu@rfrn.org>
Tue, 20 Sep 2016 16:03:19 -0700
changeset 314653 c9f2cb674778ded355d16e6d06f2fa22b49e99b3
parent 314652 005bf983f9e34c0e905830bddb4e54e9a1e1b7c1
child 314654 b10ecc57ae1a80d7b800a49dee48c509fad5040e
push id30732
push usercbook@mozilla.com
push dateWed, 21 Sep 2016 10:04:03 +0000
treeherdermozilla-central@560b2c805bf7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1303118
milestone52.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 1303118 - Fix 'this' computation for Debugger.Frame.evalWithBindings. (r=efaust)
js/src/frontend/Parser.cpp
js/src/jit-test/tests/debug/Frame-evalWithBindings-15.js
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -282,23 +282,29 @@ EvalSharedContext::EvalSharedContext(Exc
     computeThisBinding(enclosingScope);
 
     // Like all things Debugger, Debugger.Frame.eval needs special
     // handling. Since the environment chain of such evals are non-syntactic
     // (DebuggerEnvironmentProxy is not an EnvironmentObject), computing the
     // this binding with respect to enclosingScope is incorrect if the
     // Debugger.Frame is a function frame. Recompute the this binding if we
     // are such an eval.
-    if (enclosingEnv && enclosingEnv->is<DebugEnvironmentProxy>()) {
-        JSObject* env = &enclosingEnv->as<DebugEnvironmentProxy>().environment();
+    if (enclosingEnv && enclosingScope->kind() == ScopeKind::NonSyntactic) {
+        // For Debugger.Frame.eval with bindings, the environment chain may
+        // have more than the DebugEnvironmentProxy.
+        JSObject* env = enclosingEnv;
         while (env) {
+            if (env->is<DebugEnvironmentProxy>())
+                env = &env->as<DebugEnvironmentProxy>().environment();
+
             if (env->is<CallObject>()) {
                 computeThisBinding(env->as<CallObject>().callee().nonLazyScript()->bodyScope());
                 break;
             }
+
             env = env->enclosingEnvironment();
         }
     }
 }
 
 bool
 ParseContext::init()
 {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-evalWithBindings-15.js
@@ -0,0 +1,14 @@
+var g = newGlobal();
+var dbg = new Debugger(g);
+
+dbg.onDebuggerStatement = function (frame) {
+  // The bindings object is unused but adds another environment on the
+  // environment chain. Make sure 'this' computes the right value in light of
+  // this.
+  frame.evalWithBindings(`assertEq(this, foo);`, { bar: 42 });
+};
+
+g.eval(`
+var foo = { bar: function() { debugger; } };
+foo.bar();
+`);