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 |