Fix scope iteration when debugging global code.

TEST=mjsunit/debug-scopes.js

Review URL: http://codereview.chromium.org/7890007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9273 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
keuchel@chromium.org 2011-09-14 11:20:31 +00:00
parent 9d235c9dd7
commit a392f5bf70
2 changed files with 86 additions and 10 deletions

View File

@ -11031,15 +11031,16 @@ class ScopeIterator {
at_local_(false) {
// Check whether the first scope is actually a local scope.
if (context_->IsGlobalContext()) {
// If there is a stack slot for .result then this local scope has been
// created for evaluating top level code and it is not a real local scope.
// Checking for the existence of .result seems fragile, but the scope info
// saved with the code object does not otherwise have that information.
int index = function_->shared()->scope_info()->
StackSlotIndex(isolate_->heap()->result_symbol());
at_local_ = index < 0;
} else if (context_->IsFunctionContext()) {
// If there is a stack slot for .result then this local scope has been
// created for evaluating top level code and it is not a real local scope.
// Checking for the existence of .result seems fragile, but the scope info
// saved with the code object does not otherwise have that information.
int index = function_->shared()->scope_info()->
StackSlotIndex(isolate_->heap()->result_symbol());
if (index >= 0) {
local_done_ = true;
} else if (context_->IsGlobalContext() ||
context_->IsFunctionContext()) {
at_local_ = true;
} else if (context_->closure() != *function_) {
// The context_ is a block or with or catch block from the outer function.
@ -11086,7 +11087,7 @@ class ScopeIterator {
}
// Return the type of the current scope.
int Type() {
ScopeType Type() {
if (at_local_) {
return ScopeTypeLocal;
}

View File

@ -418,6 +418,27 @@ with_5();
EndTest();
// Nested with blocks using existing object in global code.
BeginTest("With 6");
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.With,
debug.ScopeType.With,
debug.ScopeType.Global], exec_state);
CheckScopeContent(with_object, 0, exec_state);
CheckScopeContent(with_object, 1, exec_state);
assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
};
var with_object = {c:3,d:4};
with(with_object) {
with(with_object) {
debugger;
}
}
EndTest();
// Simple closure formed by returning an inner function referering the outer
// functions arguments.
BeginTest("Closure 1");
@ -771,6 +792,23 @@ closure_in_with_3();
EndTest();
BeginTest("Closure inside With 4");
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.With,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x: 2}, 0, exec_state);
CheckScopeContent({x: 1}, 1, exec_state);
};
with({x:1}) {
(function(x) {
debugger;
})(2);
}
EndTest();
// Test global scope.
BeginTest("Global");
listener_delegate = function(exec_state) {
@ -875,6 +913,43 @@ catch_block_4();
EndTest();
// Test catch in global scope.
BeginTest("Catch block 5");
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Catch,
debug.ScopeType.Global], exec_state);
CheckScopeContent({e:'Exception'}, 0, exec_state);
};
try {
throw 'Exception';
} catch (e) {
debugger;
}
EndTest();
// Closure inside catch in global code.
BeginTest("Catch block 6");
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Catch,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x: 2}, 0, exec_state);
CheckScopeContent({e:'Exception'}, 1, exec_state);
};
try {
throw 'Exception';
} catch (e) {
(function(x) {
debugger;
})(2);
}
EndTest();
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,