Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index a2e569b31ece4a2cc41fe69e885154c6ad34bc49..d4186f9d7949c5fb4d9be5b6a81b42e14110dd41 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -11159,19 +11159,39 @@ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
// block context. |
static Handle<JSObject> MaterializeBlockScope( |
Isolate* isolate, |
- Handle<Context> context) { |
- ASSERT(context->IsBlockContext()); |
- Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
+ Handle<Context> context, |
+ Handle<ScopeInfo> scope_info, |
+ JavaScriptFrame* frame, |
+ int inlined_frame_index) { |
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate); |
// Allocate and initialize a JSObject with all the arguments, stack locals |
// heap locals and extension properties of the debugged function. |
Handle<JSObject> block_scope = |
isolate->factory()->NewJSObject(isolate->object_function()); |
+ // Second fill all stack locals. |
+ int stack_slots_depth = scope_info->StackSlotsDepth(); |
+ for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
+ int index = i + stack_slots_depth; |
+ RETURN_IF_EMPTY_HANDLE_VALUE( |
+ isolate, |
+ SetProperty(block_scope, |
+ Handle<String>(scope_info->StackLocalName(i)), |
+ Handle<Object>(frame_inspector.GetExpression(index)), |
+ NONE, |
+ kNonStrictMode), |
+ Handle<JSObject>()); |
+ } |
+ |
// Fill all context locals. |
- if (!CopyContextLocalsToScopeObject( |
- isolate, scope_info, context, block_scope)) { |
- return Handle<JSObject>(); |
+ if (scope_info->HasContext()) { |
+ ASSERT(context->IsBlockContext()); |
+ ASSERT(context->extension() == *scope_info); |
+ if (!CopyContextLocalsToScopeObject( |
+ isolate, scope_info, context, block_scope)) { |
+ return Handle<JSObject>(); |
+ } |
} |
return block_scope; |
@@ -11180,8 +11200,8 @@ static Handle<JSObject> MaterializeBlockScope( |
// Iterate over the actual scopes visible from a stack frame. The iteration |
// proceeds from the innermost visible nested scope outwards. All scopes are |
-// backed by an actual context except the local scope, which is inserted |
-// "artificially" in the context chain. |
+// backed by an actual context except the local function scope and local block |
+// scopes, which is inserted "artificially" in the context chain. |
class ScopeIterator { |
public: |
enum ScopeType { |
@@ -11255,13 +11275,15 @@ class ScopeIterator { |
info.MarkAsEval(); |
info.SetCallingContext(Handle<Context>(function_->context())); |
} |
- if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) { |
+ if (ParserApi::Parse(&info, kNoParsingFlags) && |
+ Compiler::MakeCode(&info)) { |
scope = info.function()->scope(); |
} |
} else { |
// Function code |
CompilationInfo info(shared_info); |
- if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) { |
+ if (ParserApi::Parse(&info, kNoParsingFlags) && |
+ Compiler::MakeCode(&info)) { |
scope = info.function()->scope(); |
} |
} |
@@ -11365,7 +11387,11 @@ class ScopeIterator { |
// Materialize the content of the closure scope into a JSObject. |
return MaterializeClosure(isolate_, CurrentContext()); |
case ScopeIterator::ScopeTypeBlock: |
- return MaterializeBlockScope(isolate_, CurrentContext()); |
+ return MaterializeBlockScope(isolate_, |
+ CurrentContext(), |
+ CurrentScopeInfo(), |
+ frame_, |
+ inlined_frame_index_); |
} |
UNREACHABLE(); |
return Handle<JSObject>(); |
@@ -11953,8 +11979,8 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
thrown_object); |
} else if (scope_info->Type() == BLOCK_SCOPE) { |
// Materialize the contents of the block scope into a JSObject. |
- Handle<JSObject> block_scope_object = |
- MaterializeBlockScope(isolate, current); |
+ Handle<JSObject> block_scope_object = MaterializeBlockScope( |
+ isolate, current, scope_info, frame, inlined_frame_index); |
if (block_scope_object.is_null()) { |
return Handle<Context>::null(); |
} |