OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug-scopes.h" | 5 #include "src/debug/debug-scopes.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/frames-inl.h" | 9 #include "src/frames-inl.h" |
10 #include "src/globals.h" | 10 #include "src/globals.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 | 66 |
67 if (ignore_nested_scopes) { | 67 if (ignore_nested_scopes) { |
68 if (scope_info->HasContext()) { | 68 if (scope_info->HasContext()) { |
69 context_ = Handle<Context>(context_->declaration_context(), isolate_); | 69 context_ = Handle<Context>(context_->declaration_context(), isolate_); |
70 } else { | 70 } else { |
71 while (context_->closure() == *function) { | 71 while (context_->closure() == *function) { |
72 context_ = Handle<Context>(context_->previous(), isolate_); | 72 context_ = Handle<Context>(context_->previous(), isolate_); |
73 } | 73 } |
74 } | 74 } |
75 if (scope_info->scope_type() == FUNCTION_SCOPE) { | 75 if (scope_info->scope_type() == FUNCTION_SCOPE) { |
76 nested_scope_chain_.Add(scope_info); | 76 nested_scope_chain_.Add(ExtendedScopeInfo(scope_info, 0, 0)); |
Yang
2016/02/25 21:25:17
the function has a start and an end position, why
sergeyv
2016/02/26 00:29:29
Done.
| |
77 } | 77 } |
78 if (!collect_non_locals) return; | 78 if (!collect_non_locals) return; |
79 } | 79 } |
80 | 80 |
81 // Reparse the code and analyze the scopes. | 81 // Reparse the code and analyze the scopes. |
82 Scope* scope = NULL; | 82 Scope* scope = NULL; |
83 // Check whether we are in global, eval or function code. | 83 // Check whether we are in global, eval or function code. |
84 Zone zone; | 84 Zone zone; |
85 if (scope_info->scope_type() != FUNCTION_SCOPE) { | 85 if (scope_info->scope_type() != FUNCTION_SCOPE) { |
86 // Global or eval code. | 86 // Global or eval code. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 | 123 |
124 MUST_USE_RESULT MaybeHandle<JSObject> ScopeIterator::MaterializeScopeDetails() { | 124 MUST_USE_RESULT MaybeHandle<JSObject> ScopeIterator::MaterializeScopeDetails() { |
125 // Calculate the size of the result. | 125 // Calculate the size of the result. |
126 Handle<FixedArray> details = | 126 Handle<FixedArray> details = |
127 isolate_->factory()->NewFixedArray(kScopeDetailsSize); | 127 isolate_->factory()->NewFixedArray(kScopeDetailsSize); |
128 // Fill in scope details. | 128 // Fill in scope details. |
129 details->set(kScopeDetailsTypeIndex, Smi::FromInt(Type())); | 129 details->set(kScopeDetailsTypeIndex, Smi::FromInt(Type())); |
130 Handle<JSObject> scope_object; | 130 Handle<JSObject> scope_object; |
131 ASSIGN_RETURN_ON_EXCEPTION(isolate_, scope_object, ScopeObject(), JSObject); | 131 ASSIGN_RETURN_ON_EXCEPTION(isolate_, scope_object, ScopeObject(), JSObject); |
132 details->set(kScopeDetailsObjectIndex, *scope_object); | 132 details->set(kScopeDetailsObjectIndex, *scope_object); |
133 if (HasContext() && CurrentContext()->closure() != NULL) { | 133 Handle<JSFunction> jsFunction = HasContext() |
Yang
2016/02/25 21:25:17
naming convention would be js_function
sergeyv
2016/02/26 00:29:29
Done.
| |
134 Handle<String> closure_name = JSFunction::GetDebugName( | 134 ? handle(CurrentContext()->closure()) |
135 Handle<JSFunction>(CurrentContext()->closure())); | 135 : Handle<JSFunction>::null(); |
136 if (!jsFunction.is_null()) { | |
137 Handle<String> closure_name = JSFunction::GetDebugName(jsFunction); | |
136 if (!closure_name.is_null() && (closure_name->length() != 0)) | 138 if (!closure_name.is_null() && (closure_name->length() != 0)) |
137 details->set(kScopeDetailsNameIndex, *closure_name); | 139 details->set(kScopeDetailsNameIndex, *closure_name); |
138 } | 140 } |
141 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript) | |
Yang
2016/02/25 21:25:17
curly brackets on line wrapped if-statement please
sergeyv
2016/02/26 00:29:29
Done.
| |
142 return isolate_->factory()->NewJSArrayWithElements(details); | |
143 | |
144 int start_position = 0; | |
145 int end_position = 0; | |
146 if (!nested_scope_chain_.is_empty()) { | |
147 jsFunction = GetFunction(); | |
148 start_position = nested_scope_chain_.last().start_position; | |
149 end_position = nested_scope_chain_.last().end_position; | |
150 } else if (!jsFunction.is_null()) { | |
151 start_position = jsFunction->shared()->start_position(); | |
152 end_position = jsFunction->shared()->end_position(); | |
153 } | |
154 | |
155 if (!jsFunction.is_null()) { | |
156 details->set(kScopeDetailsStartPositionIndex, Smi::FromInt(start_position)); | |
157 details->set(kScopeDetailsEndPositionIndex, Smi::FromInt(end_position)); | |
158 details->set(kScopeDetailsFunctionIndex, *jsFunction); | |
159 } | |
139 return isolate_->factory()->NewJSArrayWithElements(details); | 160 return isolate_->factory()->NewJSArrayWithElements(details); |
140 } | 161 } |
141 | 162 |
142 | 163 |
143 void ScopeIterator::Next() { | 164 void ScopeIterator::Next() { |
144 DCHECK(!failed_); | 165 DCHECK(!failed_); |
145 ScopeType scope_type = Type(); | 166 ScopeType scope_type = Type(); |
146 if (scope_type == ScopeTypeGlobal) { | 167 if (scope_type == ScopeTypeGlobal) { |
147 // The global scope is always the last in the chain. | 168 // The global scope is always the last in the chain. |
148 DCHECK(context_->IsNativeContext()); | 169 DCHECK(context_->IsNativeContext()); |
149 context_ = Handle<Context>(); | 170 context_ = Handle<Context>(); |
150 return; | 171 return; |
151 } | 172 } |
152 if (scope_type == ScopeTypeScript) { | 173 if (scope_type == ScopeTypeScript) { |
153 seen_script_scope_ = true; | 174 seen_script_scope_ = true; |
154 if (context_->IsScriptContext()) { | 175 if (context_->IsScriptContext()) { |
155 context_ = Handle<Context>(context_->previous(), isolate_); | 176 context_ = Handle<Context>(context_->previous(), isolate_); |
156 } | 177 } |
157 if (!nested_scope_chain_.is_empty()) { | 178 if (!nested_scope_chain_.is_empty()) { |
158 DCHECK_EQ(nested_scope_chain_.last()->scope_type(), SCRIPT_SCOPE); | 179 DCHECK_EQ(nested_scope_chain_.last().scope_info->scope_type(), |
180 SCRIPT_SCOPE); | |
159 nested_scope_chain_.RemoveLast(); | 181 nested_scope_chain_.RemoveLast(); |
160 DCHECK(nested_scope_chain_.is_empty()); | 182 DCHECK(nested_scope_chain_.is_empty()); |
161 } | 183 } |
162 CHECK(context_->IsNativeContext()); | 184 CHECK(context_->IsNativeContext()); |
163 return; | 185 return; |
164 } | 186 } |
165 if (nested_scope_chain_.is_empty()) { | 187 if (nested_scope_chain_.is_empty()) { |
166 context_ = Handle<Context>(context_->previous(), isolate_); | 188 context_ = Handle<Context>(context_->previous(), isolate_); |
167 } else { | 189 } else { |
168 if (nested_scope_chain_.last()->HasContext()) { | 190 if (nested_scope_chain_.last().scope_info->HasContext()) { |
169 DCHECK(context_->previous() != NULL); | 191 DCHECK(context_->previous() != NULL); |
170 context_ = Handle<Context>(context_->previous(), isolate_); | 192 context_ = Handle<Context>(context_->previous(), isolate_); |
171 } | 193 } |
172 nested_scope_chain_.RemoveLast(); | 194 nested_scope_chain_.RemoveLast(); |
173 } | 195 } |
174 } | 196 } |
175 | 197 |
176 | 198 |
177 // Return the type of the current scope. | 199 // Return the type of the current scope. |
178 ScopeIterator::ScopeType ScopeIterator::Type() { | 200 ScopeIterator::ScopeType ScopeIterator::Type() { |
179 DCHECK(!failed_); | 201 DCHECK(!failed_); |
180 if (!nested_scope_chain_.is_empty()) { | 202 if (!nested_scope_chain_.is_empty()) { |
181 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); | 203 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; |
182 switch (scope_info->scope_type()) { | 204 switch (scope_info->scope_type()) { |
183 case FUNCTION_SCOPE: | 205 case FUNCTION_SCOPE: |
184 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); | 206 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); |
185 return ScopeTypeLocal; | 207 return ScopeTypeLocal; |
186 case MODULE_SCOPE: | 208 case MODULE_SCOPE: |
187 DCHECK(context_->IsModuleContext()); | 209 DCHECK(context_->IsModuleContext()); |
188 return ScopeTypeModule; | 210 return ScopeTypeModule; |
189 case SCRIPT_SCOPE: | 211 case SCRIPT_SCOPE: |
190 DCHECK(context_->IsScriptContext() || context_->IsNativeContext()); | 212 DCHECK(context_->IsScriptContext() || context_->IsNativeContext()); |
191 return ScopeTypeScript; | 213 return ScopeTypeScript; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 } | 277 } |
256 UNREACHABLE(); | 278 UNREACHABLE(); |
257 return Handle<JSObject>(); | 279 return Handle<JSObject>(); |
258 } | 280 } |
259 | 281 |
260 | 282 |
261 bool ScopeIterator::HasContext() { | 283 bool ScopeIterator::HasContext() { |
262 ScopeType type = Type(); | 284 ScopeType type = Type(); |
263 if (type == ScopeTypeBlock || type == ScopeTypeLocal) { | 285 if (type == ScopeTypeBlock || type == ScopeTypeLocal) { |
264 if (!nested_scope_chain_.is_empty()) { | 286 if (!nested_scope_chain_.is_empty()) { |
265 return nested_scope_chain_.last()->HasContext(); | 287 return nested_scope_chain_.last().scope_info->HasContext(); |
266 } | 288 } |
267 } | 289 } |
268 return true; | 290 return true; |
269 } | 291 } |
270 | 292 |
271 | 293 |
272 bool ScopeIterator::SetVariableValue(Handle<String> variable_name, | 294 bool ScopeIterator::SetVariableValue(Handle<String> variable_name, |
273 Handle<Object> new_value) { | 295 Handle<Object> new_value) { |
274 DCHECK(!failed_); | 296 DCHECK(!failed_); |
275 switch (Type()) { | 297 switch (Type()) { |
(...skipping 15 matching lines...) Expand all Loading... | |
291 // TODO(2399): should we implement it? | 313 // TODO(2399): should we implement it? |
292 break; | 314 break; |
293 } | 315 } |
294 return false; | 316 return false; |
295 } | 317 } |
296 | 318 |
297 | 319 |
298 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { | 320 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { |
299 DCHECK(!failed_); | 321 DCHECK(!failed_); |
300 if (!nested_scope_chain_.is_empty()) { | 322 if (!nested_scope_chain_.is_empty()) { |
301 return nested_scope_chain_.last(); | 323 return nested_scope_chain_.last().scope_info; |
302 } else if (context_->IsBlockContext()) { | 324 } else if (context_->IsBlockContext()) { |
303 return Handle<ScopeInfo>(context_->scope_info()); | 325 return Handle<ScopeInfo>(context_->scope_info()); |
304 } else if (context_->IsFunctionContext()) { | 326 } else if (context_->IsFunctionContext()) { |
305 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | 327 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
306 } | 328 } |
307 return Handle<ScopeInfo>::null(); | 329 return Handle<ScopeInfo>::null(); |
308 } | 330 } |
309 | 331 |
310 | 332 |
311 Handle<Context> ScopeIterator::CurrentContext() { | 333 Handle<Context> ScopeIterator::CurrentContext() { |
312 DCHECK(!failed_); | 334 DCHECK(!failed_); |
313 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || | 335 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || |
314 nested_scope_chain_.is_empty()) { | 336 nested_scope_chain_.is_empty()) { |
315 return context_; | 337 return context_; |
316 } else if (nested_scope_chain_.last()->HasContext()) { | 338 } else if (nested_scope_chain_.last().scope_info->HasContext()) { |
317 return context_; | 339 return context_; |
318 } else { | 340 } else { |
319 return Handle<Context>(); | 341 return Handle<Context>(); |
320 } | 342 } |
321 } | 343 } |
322 | 344 |
323 | 345 |
324 void ScopeIterator::GetNonLocals(List<Handle<String> >* list_out) { | 346 void ScopeIterator::GetNonLocals(List<Handle<String> >* list_out) { |
325 Handle<String> this_string = isolate_->factory()->this_string(); | 347 Handle<String> this_string = isolate_->factory()->this_string(); |
326 for (HashMap::Entry* entry = non_locals_->Start(); entry != nullptr; | 348 for (HashMap::Entry* entry = non_locals_->Start(); entry != nullptr; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 UNREACHABLE(); | 424 UNREACHABLE(); |
403 } | 425 } |
404 PrintF("\n"); | 426 PrintF("\n"); |
405 } | 427 } |
406 #endif | 428 #endif |
407 | 429 |
408 | 430 |
409 void ScopeIterator::RetrieveScopeChain(Scope* scope) { | 431 void ScopeIterator::RetrieveScopeChain(Scope* scope) { |
410 if (scope != NULL) { | 432 if (scope != NULL) { |
411 int source_position = frame_inspector_->GetSourcePosition(); | 433 int source_position = frame_inspector_->GetSourcePosition(); |
412 scope->GetNestedScopeChain(isolate_, &nested_scope_chain_, source_position); | 434 GetNestedScopeChain(isolate_, scope, source_position); |
413 } else { | 435 } else { |
414 // A failed reparse indicates that the preparser has diverged from the | 436 // A failed reparse indicates that the preparser has diverged from the |
415 // parser or that the preparse data given to the initial parse has been | 437 // parser or that the preparse data given to the initial parse has been |
416 // faulty. We fail in debug mode but in release mode we only provide the | 438 // faulty. We fail in debug mode but in release mode we only provide the |
417 // information we get from the context chain but nothing about | 439 // information we get from the context chain but nothing about |
418 // completely stack allocated scopes or stack allocated locals. | 440 // completely stack allocated scopes or stack allocated locals. |
419 // Or it could be due to stack overflow. | 441 // Or it could be due to stack overflow. |
420 DCHECK(isolate_->has_pending_exception()); | 442 DCHECK(isolate_->has_pending_exception()); |
421 failed_ = true; | 443 failed_ = true; |
422 } | 444 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 | 556 |
535 | 557 |
536 // Create a plain JSObject which materializes the block scope for the specified | 558 // Create a plain JSObject which materializes the block scope for the specified |
537 // block context. | 559 // block context. |
538 Handle<JSObject> ScopeIterator::MaterializeBlockScope() { | 560 Handle<JSObject> ScopeIterator::MaterializeBlockScope() { |
539 Handle<JSObject> block_scope = | 561 Handle<JSObject> block_scope = |
540 isolate_->factory()->NewJSObject(isolate_->object_function()); | 562 isolate_->factory()->NewJSObject(isolate_->object_function()); |
541 | 563 |
542 Handle<Context> context = Handle<Context>::null(); | 564 Handle<Context> context = Handle<Context>::null(); |
543 if (!nested_scope_chain_.is_empty()) { | 565 if (!nested_scope_chain_.is_empty()) { |
544 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); | 566 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; |
545 frame_inspector_->MaterializeStackLocals(block_scope, scope_info); | 567 frame_inspector_->MaterializeStackLocals(block_scope, scope_info); |
546 if (scope_info->HasContext()) context = CurrentContext(); | 568 if (scope_info->HasContext()) context = CurrentContext(); |
547 } else { | 569 } else { |
548 context = CurrentContext(); | 570 context = CurrentContext(); |
549 } | 571 } |
550 | 572 |
551 if (!context.is_null()) { | 573 if (!context.is_null()) { |
552 // Fill all context locals. | 574 // Fill all context locals. |
553 CopyContextLocalsToScopeObject(handle(context->scope_info()), | 575 CopyContextLocalsToScopeObject(handle(context->scope_info()), |
554 context, block_scope); | 576 context, block_scope); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
808 Handle<Object> value; | 830 Handle<Object> value; |
809 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 831 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
810 isolate_, value, Object::GetPropertyOrElement(extension, key), false); | 832 isolate_, value, Object::GetPropertyOrElement(extension, key), false); |
811 RETURN_ON_EXCEPTION_VALUE( | 833 RETURN_ON_EXCEPTION_VALUE( |
812 isolate_, JSObject::SetOwnPropertyIgnoreAttributes( | 834 isolate_, JSObject::SetOwnPropertyIgnoreAttributes( |
813 scope_object, key, value, NONE), false); | 835 scope_object, key, value, NONE), false); |
814 } | 836 } |
815 return true; | 837 return true; |
816 } | 838 } |
817 | 839 |
840 void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, | |
841 int position) { | |
842 if (!scope->is_eval_scope()) | |
Yang
2016/02/25 21:25:17
curly brackets
sergeyv
2016/02/26 00:29:29
Done.
| |
843 nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate), | |
844 scope->start_position(), | |
845 scope->end_position())); | |
846 | |
847 for (int i = 0; i < scope->inner_scopes()->length(); i++) { | |
848 Scope* inner_scope = scope->inner_scopes()->at(i); | |
849 int beg_pos = inner_scope->start_position(); | |
850 int end_pos = inner_scope->end_position(); | |
851 DCHECK(beg_pos >= 0 && end_pos >= 0); | |
852 if (beg_pos <= position && position < end_pos) { | |
853 GetNestedScopeChain(isolate, inner_scope, position); | |
854 return; | |
855 } | |
856 } | |
857 } | |
858 | |
818 } // namespace internal | 859 } // namespace internal |
819 } // namespace v8 | 860 } // namespace v8 |
OLD | NEW |