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