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 2511733002: [debugger] handle stack overflow. Fail silently. (Closed)
Patch Set: fix Created 4 years 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') | no next file » | 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 <memory> 7 #include <memory>
8 8
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/debug/debug.h" 10 #include "src/debug/debug.h"
11 #include "src/frames-inl.h" 11 #include "src/frames-inl.h"
12 #include "src/globals.h" 12 #include "src/globals.h"
13 #include "src/isolate-inl.h" 13 #include "src/isolate-inl.h"
14 #include "src/parsing/parse-info.h" 14 #include "src/parsing/parse-info.h"
15 #include "src/parsing/parser.h" 15 #include "src/parsing/parser.h"
16 #include "src/parsing/rewriter.h" 16 #include "src/parsing/rewriter.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 20
21 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, 21 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
22 ScopeIterator::Option option) 22 ScopeIterator::Option option)
23 : isolate_(isolate), 23 : isolate_(isolate),
24 frame_inspector_(frame_inspector), 24 frame_inspector_(frame_inspector),
25 nested_scope_chain_(4), 25 nested_scope_chain_(4),
26 seen_script_scope_(false), 26 seen_script_scope_(false) {
27 failed_(false) {
28 if (!frame_inspector->GetContext()->IsContext()) { 27 if (!frame_inspector->GetContext()->IsContext()) {
29 // Optimized frame, context or function cannot be materialized. Give up. 28 // Optimized frame, context or function cannot be materialized. Give up.
30 return; 29 return;
31 } 30 }
32 31
33 context_ = Handle<Context>::cast(frame_inspector->GetContext()); 32 context_ = Handle<Context>::cast(frame_inspector->GetContext());
34 33
35 // We should not instantiate a ScopeIterator for wasm frames. 34 // We should not instantiate a ScopeIterator for wasm frames.
36 DCHECK(frame_inspector->GetScript()->type() != Script::TYPE_WASM); 35 DCHECK(frame_inspector->GetScript()->type() != Script::TYPE_WASM);
37 36
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } 111 }
113 if (Parser::ParseStatic(info.get()) && Rewriter::Rewrite(info.get())) { 112 if (Parser::ParseStatic(info.get()) && Rewriter::Rewrite(info.get())) {
114 DeclarationScope* scope = info->literal()->scope(); 113 DeclarationScope* scope = info->literal()->scope();
115 if (!ignore_nested_scopes || collect_non_locals) { 114 if (!ignore_nested_scopes || collect_non_locals) {
116 CollectNonLocals(info.get(), scope); 115 CollectNonLocals(info.get(), scope);
117 } 116 }
118 if (!ignore_nested_scopes) { 117 if (!ignore_nested_scopes) {
119 DeclarationScope::Analyze(info.get(), AnalyzeMode::kDebugger); 118 DeclarationScope::Analyze(info.get(), AnalyzeMode::kDebugger);
120 RetrieveScopeChain(scope); 119 RetrieveScopeChain(scope);
121 } 120 }
122 } else if (!ignore_nested_scopes) { 121 } else {
123 // A failed reparse indicates that the preparser has diverged from the 122 // A failed reparse indicates that the preparser has diverged from the
124 // parser or that the preparse data given to the initial parse has been 123 // parser or that the preparse data given to the initial parse has been
125 // faulty. We fail in debug mode but in release mode we only provide the 124 // faulty. We fail in debug mode but in release mode we only provide the
126 // information we get from the context chain but nothing about 125 // information we get from the context chain but nothing about
127 // completely stack allocated scopes or stack allocated locals. 126 // completely stack allocated scopes or stack allocated locals.
128 // Or it could be due to stack overflow. 127 // Or it could be due to stack overflow.
129 DCHECK(isolate_->has_pending_exception()); 128 // Silently fail by presenting an empty context chain.
130 failed_ = true; 129 CHECK(isolate_->has_pending_exception());
130 isolate_->clear_pending_exception();
131 context_ = Handle<Context>();
131 } 132 }
132 UnwrapEvaluationContext(); 133 UnwrapEvaluationContext();
133 } 134 }
134 135
135
136 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) 136 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
137 : isolate_(isolate), 137 : isolate_(isolate),
138 frame_inspector_(NULL), 138 frame_inspector_(NULL),
139 context_(function->context()), 139 context_(function->context()),
140 seen_script_scope_(false), 140 seen_script_scope_(false) {
141 failed_(false) {
142 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); 141 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>();
143 UnwrapEvaluationContext(); 142 UnwrapEvaluationContext();
144 } 143 }
145 144
146 ScopeIterator::ScopeIterator(Isolate* isolate, 145 ScopeIterator::ScopeIterator(Isolate* isolate,
147 Handle<JSGeneratorObject> generator) 146 Handle<JSGeneratorObject> generator)
148 : isolate_(isolate), 147 : isolate_(isolate),
149 frame_inspector_(NULL), 148 frame_inspector_(NULL),
150 context_(generator->context()), 149 context_(generator->context()),
151 seen_script_scope_(false), 150 seen_script_scope_(false) {
152 failed_(false) {
153 if (!generator->function()->shared()->IsSubjectToDebugging()) { 151 if (!generator->function()->shared()->IsSubjectToDebugging()) {
154 context_ = Handle<Context>(); 152 context_ = Handle<Context>();
155 } 153 }
156 UnwrapEvaluationContext(); 154 UnwrapEvaluationContext();
157 } 155 }
158 156
159 void ScopeIterator::UnwrapEvaluationContext() { 157 void ScopeIterator::UnwrapEvaluationContext() {
160 while (true) { 158 while (true) {
161 if (context_.is_null()) return; 159 if (context_.is_null()) return;
162 if (!context_->IsDebugEvaluateContext()) return; 160 if (!context_->IsDebugEvaluateContext()) return;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 203 }
206 details->set(kScopeDetailsStartPositionIndex, Smi::FromInt(start_position)); 204 details->set(kScopeDetailsStartPositionIndex, Smi::FromInt(start_position));
207 details->set(kScopeDetailsEndPositionIndex, Smi::FromInt(end_position)); 205 details->set(kScopeDetailsEndPositionIndex, Smi::FromInt(end_position));
208 details->set(kScopeDetailsFunctionIndex, *js_function); 206 details->set(kScopeDetailsFunctionIndex, *js_function);
209 } 207 }
210 return isolate_->factory()->NewJSArrayWithElements(details); 208 return isolate_->factory()->NewJSArrayWithElements(details);
211 } 209 }
212 210
213 211
214 void ScopeIterator::Next() { 212 void ScopeIterator::Next() {
215 DCHECK(!failed_); 213 DCHECK(!Done());
216 ScopeType scope_type = Type(); 214 ScopeType scope_type = Type();
217 if (scope_type == ScopeTypeGlobal) { 215 if (scope_type == ScopeTypeGlobal) {
218 // The global scope is always the last in the chain. 216 // The global scope is always the last in the chain.
219 DCHECK(context_->IsNativeContext()); 217 DCHECK(context_->IsNativeContext());
220 context_ = Handle<Context>(); 218 context_ = Handle<Context>();
221 } else if (scope_type == ScopeTypeScript) { 219 } else if (scope_type == ScopeTypeScript) {
222 seen_script_scope_ = true; 220 seen_script_scope_ = true;
223 if (context_->IsScriptContext()) { 221 if (context_->IsScriptContext()) {
224 context_ = Handle<Context>(context_->previous(), isolate_); 222 context_ = Handle<Context>(context_->previous(), isolate_);
225 } 223 }
(...skipping 16 matching lines...) Expand all
242 if (nested_scope_chain_.is_empty()) break; 240 if (nested_scope_chain_.is_empty()) break;
243 // Repeat to skip hidden scopes. 241 // Repeat to skip hidden scopes.
244 } while (nested_scope_chain_.last().is_hidden()); 242 } while (nested_scope_chain_.last().is_hidden());
245 } 243 }
246 UnwrapEvaluationContext(); 244 UnwrapEvaluationContext();
247 } 245 }
248 246
249 247
250 // Return the type of the current scope. 248 // Return the type of the current scope.
251 ScopeIterator::ScopeType ScopeIterator::Type() { 249 ScopeIterator::ScopeType ScopeIterator::Type() {
252 DCHECK(!failed_); 250 DCHECK(!Done());
253 if (!nested_scope_chain_.is_empty()) { 251 if (!nested_scope_chain_.is_empty()) {
254 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; 252 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info;
255 switch (scope_info->scope_type()) { 253 switch (scope_info->scope_type()) {
256 case FUNCTION_SCOPE: 254 case FUNCTION_SCOPE:
257 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); 255 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext());
258 return ScopeTypeLocal; 256 return ScopeTypeLocal;
259 case MODULE_SCOPE: 257 case MODULE_SCOPE:
260 DCHECK(context_->IsModuleContext()); 258 DCHECK(context_->IsModuleContext());
261 return ScopeTypeModule; 259 return ScopeTypeModule;
262 case SCRIPT_SCOPE: 260 case SCRIPT_SCOPE:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 } 295 }
298 if (context_->IsScriptContext()) { 296 if (context_->IsScriptContext()) {
299 return ScopeTypeScript; 297 return ScopeTypeScript;
300 } 298 }
301 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext()); 299 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext());
302 return ScopeTypeWith; 300 return ScopeTypeWith;
303 } 301 }
304 302
305 303
306 MaybeHandle<JSObject> ScopeIterator::ScopeObject() { 304 MaybeHandle<JSObject> ScopeIterator::ScopeObject() {
307 DCHECK(!failed_); 305 DCHECK(!Done());
308 switch (Type()) { 306 switch (Type()) {
309 case ScopeIterator::ScopeTypeGlobal: 307 case ScopeIterator::ScopeTypeGlobal:
310 return Handle<JSObject>(CurrentContext()->global_proxy()); 308 return Handle<JSObject>(CurrentContext()->global_proxy());
311 case ScopeIterator::ScopeTypeScript: 309 case ScopeIterator::ScopeTypeScript:
312 return MaterializeScriptScope(); 310 return MaterializeScriptScope();
313 case ScopeIterator::ScopeTypeLocal: 311 case ScopeIterator::ScopeTypeLocal:
314 // Materialize the content of the local scope into a JSObject. 312 // Materialize the content of the local scope into a JSObject.
315 DCHECK(nested_scope_chain_.length() == 1); 313 DCHECK(nested_scope_chain_.length() == 1);
316 return MaterializeLocalScope(); 314 return MaterializeLocalScope();
317 case ScopeIterator::ScopeTypeWith: 315 case ScopeIterator::ScopeTypeWith:
(...skipping 21 matching lines...) Expand all
339 if (!nested_scope_chain_.is_empty()) { 337 if (!nested_scope_chain_.is_empty()) {
340 return nested_scope_chain_.last().scope_info->HasContext(); 338 return nested_scope_chain_.last().scope_info->HasContext();
341 } 339 }
342 } 340 }
343 return true; 341 return true;
344 } 342 }
345 343
346 344
347 bool ScopeIterator::SetVariableValue(Handle<String> variable_name, 345 bool ScopeIterator::SetVariableValue(Handle<String> variable_name,
348 Handle<Object> new_value) { 346 Handle<Object> new_value) {
349 DCHECK(!failed_); 347 DCHECK(!Done());
350 switch (Type()) { 348 switch (Type()) {
351 case ScopeIterator::ScopeTypeGlobal: 349 case ScopeIterator::ScopeTypeGlobal:
352 break; 350 break;
353 case ScopeIterator::ScopeTypeLocal: 351 case ScopeIterator::ScopeTypeLocal:
354 return SetLocalVariableValue(variable_name, new_value); 352 return SetLocalVariableValue(variable_name, new_value);
355 case ScopeIterator::ScopeTypeWith: 353 case ScopeIterator::ScopeTypeWith:
356 break; 354 break;
357 case ScopeIterator::ScopeTypeCatch: 355 case ScopeIterator::ScopeTypeCatch:
358 return SetCatchVariableValue(variable_name, new_value); 356 return SetCatchVariableValue(variable_name, new_value);
359 case ScopeIterator::ScopeTypeClosure: 357 case ScopeIterator::ScopeTypeClosure:
360 return SetClosureVariableValue(variable_name, new_value); 358 return SetClosureVariableValue(variable_name, new_value);
361 case ScopeIterator::ScopeTypeScript: 359 case ScopeIterator::ScopeTypeScript:
362 return SetScriptVariableValue(variable_name, new_value); 360 return SetScriptVariableValue(variable_name, new_value);
363 case ScopeIterator::ScopeTypeBlock: 361 case ScopeIterator::ScopeTypeBlock:
364 case ScopeIterator::ScopeTypeEval: 362 case ScopeIterator::ScopeTypeEval:
365 return SetInnerScopeVariableValue(variable_name, new_value); 363 return SetInnerScopeVariableValue(variable_name, new_value);
366 case ScopeIterator::ScopeTypeModule: 364 case ScopeIterator::ScopeTypeModule:
367 // TODO(neis): Implement. 365 // TODO(neis): Implement.
368 break; 366 break;
369 } 367 }
370 return false; 368 return false;
371 } 369 }
372 370
373 371
374 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { 372 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() {
375 DCHECK(!failed_); 373 DCHECK(!Done());
376 if (!nested_scope_chain_.is_empty()) { 374 if (!nested_scope_chain_.is_empty()) {
377 return nested_scope_chain_.last().scope_info; 375 return nested_scope_chain_.last().scope_info;
378 } else if (context_->IsBlockContext()) { 376 } else if (context_->IsBlockContext()) {
379 return Handle<ScopeInfo>(context_->scope_info()); 377 return Handle<ScopeInfo>(context_->scope_info());
380 } else if (context_->IsFunctionContext()) { 378 } else if (context_->IsFunctionContext()) {
381 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); 379 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
382 } 380 }
383 return Handle<ScopeInfo>::null(); 381 return Handle<ScopeInfo>::null();
384 } 382 }
385 383
386 384
387 Handle<Context> ScopeIterator::CurrentContext() { 385 Handle<Context> ScopeIterator::CurrentContext() {
388 DCHECK(!failed_); 386 DCHECK(!Done());
389 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || 387 if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript ||
390 nested_scope_chain_.is_empty()) { 388 nested_scope_chain_.is_empty()) {
391 return context_; 389 return context_;
392 } else if (nested_scope_chain_.last().scope_info->HasContext()) { 390 } else if (nested_scope_chain_.last().scope_info->HasContext()) {
393 return context_; 391 return context_;
394 } else { 392 } else {
395 return Handle<Context>(); 393 return Handle<Context>();
396 } 394 }
397 } 395 }
398 396
399 Handle<StringSet> ScopeIterator::GetNonLocals() { return non_locals_; } 397 Handle<StringSet> ScopeIterator::GetNonLocals() { return non_locals_; }
400 398
401 #ifdef DEBUG 399 #ifdef DEBUG
402 // Debug print of the content of the current scope. 400 // Debug print of the content of the current scope.
403 void ScopeIterator::DebugPrint() { 401 void ScopeIterator::DebugPrint() {
404 OFStream os(stdout); 402 OFStream os(stdout);
405 DCHECK(!failed_); 403 DCHECK(!Done());
406 switch (Type()) { 404 switch (Type()) {
407 case ScopeIterator::ScopeTypeGlobal: 405 case ScopeIterator::ScopeTypeGlobal:
408 os << "Global:\n"; 406 os << "Global:\n";
409 CurrentContext()->Print(os); 407 CurrentContext()->Print(os);
410 break; 408 break;
411 409
412 case ScopeIterator::ScopeTypeLocal: { 410 case ScopeIterator::ScopeTypeLocal: {
413 os << "Local:\n"; 411 os << "Local:\n";
414 GetFunction()->shared()->scope_info()->Print(); 412 GetFunction()->shared()->scope_info()->Print();
415 if (!CurrentContext().is_null()) { 413 if (!CurrentContext().is_null()) {
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); 854 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden());
857 if (beg_pos <= position && position < end_pos) { 855 if (beg_pos <= position && position < end_pos) {
858 GetNestedScopeChain(isolate, inner_scope, position); 856 GetNestedScopeChain(isolate, inner_scope, position);
859 return; 857 return;
860 } 858 }
861 } 859 }
862 } 860 }
863 861
864 } // namespace internal 862 } // namespace internal
865 } // namespace v8 863 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug-scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698