Chromium Code Reviews| 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 |