Revision: 15323
Author:   [email protected]
Date:     Tue Jun 25 06:48:43 2013
Log:      Allow debugger evaluate expressions to mute local variables

[email protected]

Review URL: https://codereview.chromium.org/17636007
http://code.google.com/p/v8/source/detail?r=15323

Modified:
 /branches/bleeding_edge/src/mirror-debugger.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/test/mjsunit/debug-evaluate-locals.js

=======================================
--- /branches/bleeding_edge/src/mirror-debugger.js      Tue Jun 25 06:42:44 2013
+++ /branches/bleeding_edge/src/mirror-debugger.js      Tue Jun 25 06:48:43 2013
@@ -1699,13 +1699,30 @@

 FrameMirror.prototype.evaluate = function(source, disable_break,
                                           opt_context_object) {
-  var result = %DebugEvaluate(this.break_id_,
-                              this.details_.frameId(),
-                              this.details_.inlinedFrameIndex(),
-                              source,
-                              Boolean(disable_break),
-                              opt_context_object);
-  return MakeMirror(result);
+  var result_array = %DebugEvaluate(this.break_id_,
+                                    this.details_.frameId(),
+                                    this.details_.inlinedFrameIndex(),
+                                    source,
+                                    Boolean(disable_break),
+                                    opt_context_object);
+  // Silently ignore local variables changes if the frame is optimized.
+  if (!this.isOptimizedFrame()) {
+    var local_scope_before = result_array[1];
+    var local_scope_after = result_array[2];
+    for (var n in local_scope_after) {
+      var value_before = local_scope_before[n];
+      var value_after = local_scope_after[n];
+      if (value_before !== value_after) {
+        %SetScopeVariableValue(this.break_id_,
+                               this.details_.frameId(),
+                               this.details_.inlinedFrameIndex(),
+                               0,
+                               n,
+                               value_after);
+      }
+    }
+  }
+  return MakeMirror(result_array[0]);
 };


=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Jun 25 06:42:44 2013
+++ /branches/bleeding_edge/src/runtime.cc      Tue Jun 25 06:48:43 2013
@@ -12424,6 +12424,13 @@
 // the same view of the values of parameters and local variables as if the
 // piece of JavaScript was evaluated at the point where the function on the
// stack frame is currently stopped when we compile and run the (direct) eval.
+// Returns array of
+// #0: evaluate result
+// #1: local variables scope materizalized as object before evaluation
+// #2: local variables scope materizalized as object after evaluation
+// Since user expression only reaches (and modifies) copies of local variables, +// those copies are returned to the caller to allow tracking the changes and
+// manually updating the actual variables.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   HandleScope scope(isolate);

@@ -12523,7 +12530,23 @@
   }

   Handle<Object> receiver(frame->receiver(), isolate);
- return DebugEvaluate(isolate, context, context_extension, receiver, source);
+  Object* evaluate_result_object;
+  { MaybeObject* maybe_result =
+    DebugEvaluate(isolate, context, context_extension, receiver, source);
+ if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
+  }
+  Handle<Object> evaluate_result(evaluate_result_object, isolate);
+
+ Handle<JSObject> local_scope_after = MaterializeLocalScopeWithFrameInspector(
+      isolate, frame, &frame_inspector);
+
+  Handle<FixedArray> resultArray =
+      isolate->factory()->NewFixedArray(3);
+  resultArray->set(0, *evaluate_result);
+  resultArray->set(2, *local_scope);
+  resultArray->set(1, *local_scope_after);
+
+  return *(isolate->factory()->NewJSArrayWithElements(resultArray));
 }


=======================================
--- /branches/bleeding_edge/test/mjsunit/debug-evaluate-locals.js Thu Mar 21 01:50:29 2013 +++ /branches/bleeding_edge/test/mjsunit/debug-evaluate-locals.js Tue Jun 25 06:48:43 2013
@@ -38,6 +38,7 @@
   var b = 2;
   var eval = 5;  // Overriding eval should not break anything.
   debugger;  // Breakpoint.
+  return a;
 }

 function checkFrame0(frame) {
@@ -60,7 +61,7 @@
 function g() {
   var a = 3;
   eval("var b = 4;");
-  h();
+  return h() + a;
 }

 function checkFrame1(frame) {
@@ -83,7 +84,7 @@
   var a = 5;
   var b = 0;
   with ({b:6}) {
-    g();
+    return g();
   }
 }

@@ -125,6 +126,10 @@
       assertEquals(6, exec_state.frame(2).evaluate('b').value());
       assertEquals("function",
                    typeof exec_state.frame(2).evaluate('eval').value());
+      assertEquals("foo",
+                   exec_state.frame(0).evaluate('a = "foo"').value());
+      assertEquals("bar",
+                   exec_state.frame(1).evaluate('a = "bar"').value());
       // Indicate that all was processed.
       listenerComplete = true;
     }
@@ -137,7 +142,9 @@
 // Add the debug event listener.
 Debug.setListener(listener);

-f();
+var f_result = f();
+
+assertEquals('foobar', f_result);

 // Make sure that the debug event listener was invoked.
 assertFalse(exception, "exception in listener")

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to