diff --git a/src/runtime.cc b/src/runtime.cc index 00999db6ee..b7db295c2e 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -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; } diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js index 40adf5b2d2..1c23b0bf99 100644 --- a/test/mjsunit/debug-scopes.js +++ b/test/mjsunit/debug-scopes.js @@ -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,