| 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" |
| 11 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
| 12 #include "src/parsing/parser.h" | 12 #include "src/parsing/parser.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, | 17 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, |
| 18 ScopeIterator::Option option) | 18 ScopeIterator::Option option) |
| 19 : isolate_(isolate), | 19 : isolate_(isolate), |
| 20 frame_inspector_(frame_inspector), | 20 frame_inspector_(frame_inspector), |
| 21 nested_scope_chain_(4), | 21 nested_scope_chain_(4), |
| 22 non_locals_(nullptr), | |
| 23 seen_script_scope_(false), | 22 seen_script_scope_(false), |
| 24 failed_(false) { | 23 failed_(false) { |
| 25 if (!frame_inspector->GetContext()->IsContext() || | 24 if (!frame_inspector->GetContext()->IsContext() || |
| 26 !frame_inspector->GetFunction()->IsJSFunction()) { | 25 !frame_inspector->GetFunction()->IsJSFunction()) { |
| 27 // Optimized frame, context or function cannot be materialized. Give up. | 26 // Optimized frame, context or function cannot be materialized. Give up. |
| 28 return; | 27 return; |
| 29 } | 28 } |
| 30 | 29 |
| 31 context_ = Handle<Context>::cast(frame_inspector->GetContext()); | 30 context_ = Handle<Context>::cast(frame_inspector->GetContext()); |
| 32 | 31 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 if (!ignore_nested_scopes) RetrieveScopeChain(scope); | 108 if (!ignore_nested_scopes) RetrieveScopeChain(scope); |
| 110 if (collect_non_locals) CollectNonLocals(scope); | 109 if (collect_non_locals) CollectNonLocals(scope); |
| 111 } | 110 } |
| 112 } | 111 } |
| 113 | 112 |
| 114 | 113 |
| 115 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) | 114 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) |
| 116 : isolate_(isolate), | 115 : isolate_(isolate), |
| 117 frame_inspector_(NULL), | 116 frame_inspector_(NULL), |
| 118 context_(function->context()), | 117 context_(function->context()), |
| 119 non_locals_(nullptr), | |
| 120 seen_script_scope_(false), | 118 seen_script_scope_(false), |
| 121 failed_(false) { | 119 failed_(false) { |
| 122 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); | 120 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); |
| 123 } | 121 } |
| 124 | 122 |
| 125 | 123 |
| 126 MUST_USE_RESULT MaybeHandle<JSObject> ScopeIterator::MaterializeScopeDetails() { | 124 MUST_USE_RESULT MaybeHandle<JSObject> ScopeIterator::MaterializeScopeDetails() { |
| 127 // Calculate the size of the result. | 125 // Calculate the size of the result. |
| 128 Handle<FixedArray> details = | 126 Handle<FixedArray> details = |
| 129 isolate_->factory()->NewFixedArray(kScopeDetailsSize); | 127 isolate_->factory()->NewFixedArray(kScopeDetailsSize); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 case FUNCTION_SCOPE: | 205 case FUNCTION_SCOPE: |
| 208 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); | 206 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); |
| 209 return ScopeTypeLocal; | 207 return ScopeTypeLocal; |
| 210 case MODULE_SCOPE: | 208 case MODULE_SCOPE: |
| 211 DCHECK(context_->IsModuleContext()); | 209 DCHECK(context_->IsModuleContext()); |
| 212 return ScopeTypeModule; | 210 return ScopeTypeModule; |
| 213 case SCRIPT_SCOPE: | 211 case SCRIPT_SCOPE: |
| 214 DCHECK(context_->IsScriptContext() || context_->IsNativeContext()); | 212 DCHECK(context_->IsScriptContext() || context_->IsNativeContext()); |
| 215 return ScopeTypeScript; | 213 return ScopeTypeScript; |
| 216 case WITH_SCOPE: | 214 case WITH_SCOPE: |
| 217 DCHECK(context_->IsWithContext()); | 215 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext()); |
| 218 return ScopeTypeWith; | 216 return ScopeTypeWith; |
| 219 case CATCH_SCOPE: | 217 case CATCH_SCOPE: |
| 220 DCHECK(context_->IsCatchContext()); | 218 DCHECK(context_->IsCatchContext()); |
| 221 return ScopeTypeCatch; | 219 return ScopeTypeCatch; |
| 222 case BLOCK_SCOPE: | 220 case BLOCK_SCOPE: |
| 223 DCHECK(!scope_info->HasContext() || context_->IsBlockContext()); | 221 DCHECK(!scope_info->HasContext() || context_->IsBlockContext()); |
| 224 return ScopeTypeBlock; | 222 return ScopeTypeBlock; |
| 225 case EVAL_SCOPE: | 223 case EVAL_SCOPE: |
| 226 UNREACHABLE(); | 224 UNREACHABLE(); |
| 227 } | 225 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 240 } | 238 } |
| 241 if (context_->IsBlockContext()) { | 239 if (context_->IsBlockContext()) { |
| 242 return ScopeTypeBlock; | 240 return ScopeTypeBlock; |
| 243 } | 241 } |
| 244 if (context_->IsModuleContext()) { | 242 if (context_->IsModuleContext()) { |
| 245 return ScopeTypeModule; | 243 return ScopeTypeModule; |
| 246 } | 244 } |
| 247 if (context_->IsScriptContext()) { | 245 if (context_->IsScriptContext()) { |
| 248 return ScopeTypeScript; | 246 return ScopeTypeScript; |
| 249 } | 247 } |
| 250 DCHECK(context_->IsWithContext()); | 248 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext()); |
| 251 return ScopeTypeWith; | 249 return ScopeTypeWith; |
| 252 } | 250 } |
| 253 | 251 |
| 254 | 252 |
| 255 MaybeHandle<JSObject> ScopeIterator::ScopeObject() { | 253 MaybeHandle<JSObject> ScopeIterator::ScopeObject() { |
| 256 DCHECK(!failed_); | 254 DCHECK(!failed_); |
| 257 switch (Type()) { | 255 switch (Type()) { |
| 258 case ScopeIterator::ScopeTypeGlobal: | 256 case ScopeIterator::ScopeTypeGlobal: |
| 259 return Handle<JSObject>(CurrentContext()->global_proxy()); | 257 return Handle<JSObject>(CurrentContext()->global_proxy()); |
| 260 case ScopeIterator::ScopeTypeScript: | 258 case ScopeIterator::ScopeTypeScript: |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || | 335 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || |
| 338 nested_scope_chain_.is_empty()) { | 336 nested_scope_chain_.is_empty()) { |
| 339 return context_; | 337 return context_; |
| 340 } else if (nested_scope_chain_.last().scope_info->HasContext()) { | 338 } else if (nested_scope_chain_.last().scope_info->HasContext()) { |
| 341 return context_; | 339 return context_; |
| 342 } else { | 340 } else { |
| 343 return Handle<Context>(); | 341 return Handle<Context>(); |
| 344 } | 342 } |
| 345 } | 343 } |
| 346 | 344 |
| 347 | 345 Handle<StringSet> ScopeIterator::GetNonLocals() { return non_locals_; } |
| 348 void ScopeIterator::GetNonLocals(List<Handle<String> >* list_out) { | |
| 349 Handle<String> this_string = isolate_->factory()->this_string(); | |
| 350 for (HashMap::Entry* entry = non_locals_->Start(); entry != nullptr; | |
| 351 entry = non_locals_->Next(entry)) { | |
| 352 Handle<String> name(reinterpret_cast<String**>(entry->key)); | |
| 353 // We need to treat "this" differently. | |
| 354 if (name.is_identical_to(this_string)) continue; | |
| 355 list_out->Add(Handle<String>(reinterpret_cast<String**>(entry->key))); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 | |
| 360 bool ScopeIterator::ThisIsNonLocal() { | |
| 361 Handle<String> this_string = isolate_->factory()->this_string(); | |
| 362 void* key = reinterpret_cast<void*>(this_string.location()); | |
| 363 HashMap::Entry* entry = non_locals_->Lookup(key, this_string->Hash()); | |
| 364 return entry != nullptr; | |
| 365 } | |
| 366 | |
| 367 | 346 |
| 368 #ifdef DEBUG | 347 #ifdef DEBUG |
| 369 // Debug print of the content of the current scope. | 348 // Debug print of the content of the current scope. |
| 370 void ScopeIterator::DebugPrint() { | 349 void ScopeIterator::DebugPrint() { |
| 371 OFStream os(stdout); | 350 OFStream os(stdout); |
| 372 DCHECK(!failed_); | 351 DCHECK(!failed_); |
| 373 switch (Type()) { | 352 switch (Type()) { |
| 374 case ScopeIterator::ScopeTypeGlobal: | 353 case ScopeIterator::ScopeTypeGlobal: |
| 375 os << "Global:\n"; | 354 os << "Global:\n"; |
| 376 CurrentContext()->Print(os); | 355 CurrentContext()->Print(os); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 // completely stack allocated scopes or stack allocated locals. | 421 // completely stack allocated scopes or stack allocated locals. |
| 443 // Or it could be due to stack overflow. | 422 // Or it could be due to stack overflow. |
| 444 DCHECK(isolate_->has_pending_exception()); | 423 DCHECK(isolate_->has_pending_exception()); |
| 445 failed_ = true; | 424 failed_ = true; |
| 446 } | 425 } |
| 447 } | 426 } |
| 448 | 427 |
| 449 | 428 |
| 450 void ScopeIterator::CollectNonLocals(Scope* scope) { | 429 void ScopeIterator::CollectNonLocals(Scope* scope) { |
| 451 if (scope != NULL) { | 430 if (scope != NULL) { |
| 452 DCHECK_NULL(non_locals_); | 431 DCHECK(non_locals_.is_null()); |
| 453 non_locals_ = new HashMap(InternalizedStringMatch); | 432 non_locals_ = scope->CollectNonLocals(StringSet::New(isolate_)); |
| 454 scope->CollectNonLocals(non_locals_); | |
| 455 } | 433 } |
| 456 } | 434 } |
| 457 | 435 |
| 458 | 436 |
| 459 MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() { | 437 MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() { |
| 460 Handle<JSGlobalObject> global(CurrentContext()->global_object()); | 438 Handle<JSGlobalObject> global(CurrentContext()->global_object()); |
| 461 Handle<ScriptContextTable> script_contexts( | 439 Handle<ScriptContextTable> script_contexts( |
| 462 global->native_context()->script_context_table()); | 440 global->native_context()->script_context_table()); |
| 463 | 441 |
| 464 Handle<JSObject> script_scope = | 442 Handle<JSObject> script_scope = |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 DCHECK(beg_pos >= 0 && end_pos >= 0); | 831 DCHECK(beg_pos >= 0 && end_pos >= 0); |
| 854 if (beg_pos <= position && position < end_pos) { | 832 if (beg_pos <= position && position < end_pos) { |
| 855 GetNestedScopeChain(isolate, inner_scope, position); | 833 GetNestedScopeChain(isolate, inner_scope, position); |
| 856 return; | 834 return; |
| 857 } | 835 } |
| 858 } | 836 } |
| 859 } | 837 } |
| 860 | 838 |
| 861 } // namespace internal | 839 } // namespace internal |
| 862 } // namespace v8 | 840 } // namespace v8 |
| OLD | NEW |