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.