Allow debugger evaluate expressions to mute local variables
R=yangguo@chromium.org Review URL: https://codereview.chromium.org/17636007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15323 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
cecbe44e42
commit
42a10a9dfe
@ -1699,13 +1699,30 @@ FrameMirror.prototype.stepInPositions = function() {
|
|||||||
|
|
||||||
FrameMirror.prototype.evaluate = function(source, disable_break,
|
FrameMirror.prototype.evaluate = function(source, disable_break,
|
||||||
opt_context_object) {
|
opt_context_object) {
|
||||||
var result = %DebugEvaluate(this.break_id_,
|
var result_array = %DebugEvaluate(this.break_id_,
|
||||||
this.details_.frameId(),
|
this.details_.frameId(),
|
||||||
this.details_.inlinedFrameIndex(),
|
this.details_.inlinedFrameIndex(),
|
||||||
source,
|
source,
|
||||||
Boolean(disable_break),
|
Boolean(disable_break),
|
||||||
opt_context_object);
|
opt_context_object);
|
||||||
return MakeMirror(result);
|
// 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]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -12424,6 +12424,13 @@ static MaybeObject* DebugEvaluate(Isolate* isolate,
|
|||||||
// the same view of the values of parameters and local variables as if the
|
// 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
|
// 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.
|
// 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) {
|
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
|
|
||||||
@ -12523,7 +12530,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> receiver(frame->receiver(), isolate);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ function h() {
|
|||||||
var b = 2;
|
var b = 2;
|
||||||
var eval = 5; // Overriding eval should not break anything.
|
var eval = 5; // Overriding eval should not break anything.
|
||||||
debugger; // Breakpoint.
|
debugger; // Breakpoint.
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFrame0(frame) {
|
function checkFrame0(frame) {
|
||||||
@ -60,7 +61,7 @@ function checkFrame0(frame) {
|
|||||||
function g() {
|
function g() {
|
||||||
var a = 3;
|
var a = 3;
|
||||||
eval("var b = 4;");
|
eval("var b = 4;");
|
||||||
h();
|
return h() + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFrame1(frame) {
|
function checkFrame1(frame) {
|
||||||
@ -83,7 +84,7 @@ function f() {
|
|||||||
var a = 5;
|
var a = 5;
|
||||||
var b = 0;
|
var b = 0;
|
||||||
with ({b:6}) {
|
with ({b:6}) {
|
||||||
g();
|
return g();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +126,10 @@ function listener(event, exec_state, event_data, data) {
|
|||||||
assertEquals(6, exec_state.frame(2).evaluate('b').value());
|
assertEquals(6, exec_state.frame(2).evaluate('b').value());
|
||||||
assertEquals("function",
|
assertEquals("function",
|
||||||
typeof exec_state.frame(2).evaluate('eval').value());
|
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.
|
// Indicate that all was processed.
|
||||||
listenerComplete = true;
|
listenerComplete = true;
|
||||||
}
|
}
|
||||||
@ -137,7 +142,9 @@ function listener(event, exec_state, event_data, data) {
|
|||||||
// Add the debug event listener.
|
// Add the debug event listener.
|
||||||
Debug.setListener(listener);
|
Debug.setListener(listener);
|
||||||
|
|
||||||
f();
|
var f_result = f();
|
||||||
|
|
||||||
|
assertEquals('foobar', f_result);
|
||||||
|
|
||||||
// Make sure that the debug event listener was invoked.
|
// Make sure that the debug event listener was invoked.
|
||||||
assertFalse(exception, "exception in listener")
|
assertFalse(exception, "exception in listener")
|
||||||
|
Loading…
Reference in New Issue
Block a user