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,
|
||||
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]);
|
||||
};
|
||||
|
||||
|
||||
|
@ -12424,6 +12424,13 @@ static MaybeObject* DebugEvaluate(Isolate* isolate,
|
||||
// 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 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
|
||||
}
|
||||
|
||||
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 eval = 5; // Overriding eval should not break anything.
|
||||
debugger; // Breakpoint.
|
||||
return a;
|
||||
}
|
||||
|
||||
function checkFrame0(frame) {
|
||||
@ -60,7 +61,7 @@ function checkFrame0(frame) {
|
||||
function g() {
|
||||
var a = 3;
|
||||
eval("var b = 4;");
|
||||
h();
|
||||
return h() + a;
|
||||
}
|
||||
|
||||
function checkFrame1(frame) {
|
||||
@ -83,7 +84,7 @@ function f() {
|
||||
var a = 5;
|
||||
var b = 0;
|
||||
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("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 @@ function listener(event, exec_state, event_data, data) {
|
||||
// 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")
|
||||
|
Loading…
Reference in New Issue
Block a user