Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/debug/debug-scopes.cc

Issue 1653083002: Devtools: expose scopes source location to debugger (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/debug/debug-scopes.h ('k') | src/debug/mirrors.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/debug/debug-scopes.h ('k') | src/debug/mirrors.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698