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 <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 ScopeIterator::Option option) | 23 ScopeIterator::Option option) |
24 : isolate_(isolate), | 24 : isolate_(isolate), |
25 frame_inspector_(frame_inspector), | 25 frame_inspector_(frame_inspector), |
26 nested_scope_chain_(4), | 26 nested_scope_chain_(4), |
27 seen_script_scope_(false) { | 27 seen_script_scope_(false) { |
28 if (!frame_inspector->GetContext()->IsContext()) { | 28 if (!frame_inspector->GetContext()->IsContext()) { |
29 // Optimized frame, context or function cannot be materialized. Give up. | 29 // Optimized frame, context or function cannot be materialized. Give up. |
30 return; | 30 return; |
31 } | 31 } |
32 | 32 |
| 33 context_ = Handle<Context>::cast(frame_inspector->GetContext()); |
| 34 |
33 // We should not instantiate a ScopeIterator for wasm frames. | 35 // We should not instantiate a ScopeIterator for wasm frames. |
34 DCHECK(frame_inspector->GetScript()->type() != Script::TYPE_WASM); | 36 DCHECK(frame_inspector->GetScript()->type() != Script::TYPE_WASM); |
35 | 37 |
36 TryParseAndRetrieveScopes(option); | |
37 } | |
38 | |
39 void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) { | |
40 context_ = GetContext(); | |
41 | |
42 // Catch the case when the debugger stops in an internal function. | 38 // Catch the case when the debugger stops in an internal function. |
43 Handle<JSFunction> function = GetFunction(); | 39 Handle<JSFunction> function = GetFunction(); |
44 Handle<SharedFunctionInfo> shared_info(function->shared()); | 40 Handle<SharedFunctionInfo> shared_info(function->shared()); |
45 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 41 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
46 if (shared_info->script()->IsUndefined(isolate_)) { | 42 if (shared_info->script()->IsUndefined(isolate)) { |
47 while (context_->closure() == *function) { | 43 while (context_->closure() == *function) { |
48 context_ = Handle<Context>(context_->previous(), isolate_); | 44 context_ = Handle<Context>(context_->previous(), isolate_); |
49 } | 45 } |
50 return; | 46 return; |
51 } | 47 } |
52 | 48 |
53 // Currently it takes too much time to find nested scopes due to script | 49 // Currently it takes too much time to find nested scopes due to script |
54 // parsing. Sometimes we want to run the ScopeIterator as fast as possible | 50 // parsing. Sometimes we want to run the ScopeIterator as fast as possible |
55 // (for example, while collecting async call stacks on every | 51 // (for example, while collecting async call stacks on every |
56 // addEventListener call), even if we drop some nested scopes. | 52 // addEventListener call), even if we drop some nested scopes. |
57 // Later we may optimize getting the nested scopes (cache the result?) | 53 // Later we may optimize getting the nested scopes (cache the result?) |
58 // and include nested scopes into the "fast" iteration case as well. | 54 // and include nested scopes into the "fast" iteration case as well. |
59 bool ignore_nested_scopes = (option == IGNORE_NESTED_SCOPES); | 55 bool ignore_nested_scopes = (option == IGNORE_NESTED_SCOPES); |
60 bool collect_non_locals = (option == COLLECT_NON_LOCALS); | 56 bool collect_non_locals = (option == COLLECT_NON_LOCALS); |
61 if (!ignore_nested_scopes && shared_info->HasDebugInfo() && | 57 if (!ignore_nested_scopes && shared_info->HasDebugInfo()) { |
62 frame_inspector_ != nullptr) { | |
63 // The source position at return is always the end of the function, | 58 // The source position at return is always the end of the function, |
64 // which is not consistent with the current scope chain. Therefore all | 59 // which is not consistent with the current scope chain. Therefore all |
65 // nested with, catch and block contexts are skipped, and we can only | 60 // nested with, catch and block contexts are skipped, and we can only |
66 // inspect the function scope. | 61 // inspect the function scope. |
67 // This can only happen if we set a break point inside right before the | 62 // This can only happen if we set a break point inside right before the |
68 // return, which requires a debug info to be available. | 63 // return, which requires a debug info to be available. |
69 Handle<DebugInfo> debug_info(shared_info->GetDebugInfo()); | 64 Handle<DebugInfo> debug_info(shared_info->GetDebugInfo()); |
70 | 65 |
71 // Find the break point where execution has stopped. | 66 // Find the break point where execution has stopped. |
72 BreakLocation location = BreakLocation::FromFrame(debug_info, GetFrame()); | 67 BreakLocation location = BreakLocation::FromFrame(debug_info, GetFrame()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 info->set_language_mode(shared_info->language_mode()); | 102 info->set_language_mode(shared_info->language_mode()); |
108 } else if (scope_info->scope_type() == MODULE_SCOPE) { | 103 } else if (scope_info->scope_type() == MODULE_SCOPE) { |
109 info->set_module(); | 104 info->set_module(); |
110 } else { | 105 } else { |
111 DCHECK(scope_info->scope_type() == SCRIPT_SCOPE); | 106 DCHECK(scope_info->scope_type() == SCRIPT_SCOPE); |
112 } | 107 } |
113 } else { | 108 } else { |
114 // Inner function. | 109 // Inner function. |
115 info.reset(new ParseInfo(shared_info)); | 110 info.reset(new ParseInfo(shared_info)); |
116 } | 111 } |
117 if (parsing::ParseAny(info.get(), isolate_) && | 112 if (parsing::ParseAny(info.get(), isolate) && |
118 Rewriter::Rewrite(info.get(), isolate_)) { | 113 Rewriter::Rewrite(info.get(), isolate)) { |
119 DeclarationScope* scope = info->literal()->scope(); | 114 DeclarationScope* scope = info->literal()->scope(); |
120 if (!ignore_nested_scopes || collect_non_locals) { | 115 if (!ignore_nested_scopes || collect_non_locals) { |
121 CollectNonLocals(info.get(), scope); | 116 CollectNonLocals(info.get(), scope); |
122 } | 117 } |
123 if (!ignore_nested_scopes) { | 118 if (!ignore_nested_scopes) { |
124 DeclarationScope::Analyze(info.get(), isolate_, AnalyzeMode::kDebugger); | 119 DeclarationScope::Analyze(info.get(), isolate_, AnalyzeMode::kDebugger); |
125 RetrieveScopeChain(scope); | 120 RetrieveScopeChain(scope); |
126 } | 121 } |
127 } else { | 122 } else { |
128 // A failed reparse indicates that the preparser has diverged from the | 123 // A failed reparse indicates that the preparser has diverged from the |
129 // parser or that the preparse data given to the initial parse has been | 124 // parser or that the preparse data given to the initial parse has been |
130 // faulty. We fail in debug mode but in release mode we only provide the | 125 // faulty. We fail in debug mode but in release mode we only provide the |
131 // information we get from the context chain but nothing about | 126 // information we get from the context chain but nothing about |
132 // completely stack allocated scopes or stack allocated locals. | 127 // completely stack allocated scopes or stack allocated locals. |
133 // Or it could be due to stack overflow. | 128 // Or it could be due to stack overflow. |
134 // Silently fail by presenting an empty context chain. | 129 // Silently fail by presenting an empty context chain. |
135 CHECK(isolate_->has_pending_exception()); | 130 CHECK(isolate_->has_pending_exception()); |
136 isolate_->clear_pending_exception(); | 131 isolate_->clear_pending_exception(); |
137 context_ = Handle<Context>(); | 132 context_ = Handle<Context>(); |
138 } | 133 } |
139 UnwrapEvaluationContext(); | 134 UnwrapEvaluationContext(); |
140 } | 135 } |
141 | 136 |
142 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) | 137 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) |
143 : isolate_(isolate), | 138 : isolate_(isolate), |
| 139 frame_inspector_(NULL), |
144 context_(function->context()), | 140 context_(function->context()), |
145 seen_script_scope_(false) { | 141 seen_script_scope_(false) { |
146 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); | 142 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); |
147 UnwrapEvaluationContext(); | 143 UnwrapEvaluationContext(); |
148 } | 144 } |
149 | 145 |
150 ScopeIterator::ScopeIterator(Isolate* isolate, | 146 ScopeIterator::ScopeIterator(Isolate* isolate, |
151 Handle<JSGeneratorObject> generator) | 147 Handle<JSGeneratorObject> generator) |
152 : isolate_(isolate), | 148 : isolate_(isolate), |
153 generator_(generator), | 149 frame_inspector_(NULL), |
154 context_(generator->context()), | 150 context_(generator->context()), |
155 seen_script_scope_(false) { | 151 seen_script_scope_(false) { |
156 if (!generator->function()->shared()->IsSubjectToDebugging()) { | 152 if (!generator->function()->shared()->IsSubjectToDebugging()) { |
157 context_ = Handle<Context>(); | 153 context_ = Handle<Context>(); |
158 return; | |
159 } | 154 } |
160 TryParseAndRetrieveScopes(DEFAULT); | 155 UnwrapEvaluationContext(); |
161 } | 156 } |
162 | 157 |
163 void ScopeIterator::UnwrapEvaluationContext() { | 158 void ScopeIterator::UnwrapEvaluationContext() { |
164 while (true) { | 159 while (true) { |
165 if (context_.is_null()) return; | 160 if (context_.is_null()) return; |
166 if (!context_->IsDebugEvaluateContext()) return; | 161 if (!context_->IsDebugEvaluateContext()) return; |
167 Handle<Object> wrapped(context_->get(Context::WRAPPED_CONTEXT_INDEX), | 162 Handle<Object> wrapped(context_->get(Context::WRAPPED_CONTEXT_INDEX), |
168 isolate_); | 163 isolate_); |
169 if (wrapped->IsContext()) { | 164 if (wrapped->IsContext()) { |
170 context_ = Handle<Context>::cast(wrapped); | 165 context_ = Handle<Context>::cast(wrapped); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 ->Print(os); | 452 ->Print(os); |
458 break; | 453 break; |
459 | 454 |
460 default: | 455 default: |
461 UNREACHABLE(); | 456 UNREACHABLE(); |
462 } | 457 } |
463 PrintF("\n"); | 458 PrintF("\n"); |
464 } | 459 } |
465 #endif | 460 #endif |
466 | 461 |
467 inline Handle<Context> ScopeIterator::GetContext() { | |
468 if (frame_inspector_) { | |
469 return Handle<Context>::cast(frame_inspector_->GetContext()); | |
470 } else { | |
471 DCHECK(!generator_.is_null()); | |
472 return handle(generator_->context()); | |
473 } | |
474 } | |
475 | |
476 Handle<JSFunction> ScopeIterator::GetFunction() { | |
477 if (frame_inspector_) { | |
478 return frame_inspector_->GetFunction(); | |
479 } else { | |
480 DCHECK(!generator_.is_null()); | |
481 return handle(generator_->function()); | |
482 } | |
483 } | |
484 | |
485 int ScopeIterator::GetSourcePosition() { | |
486 if (frame_inspector_) { | |
487 return frame_inspector_->GetSourcePosition(); | |
488 } else { | |
489 DCHECK(!generator_.is_null()); | |
490 return generator_->source_position(); | |
491 } | |
492 } | |
493 | |
494 void ScopeIterator::RetrieveScopeChain(DeclarationScope* scope) { | 462 void ScopeIterator::RetrieveScopeChain(DeclarationScope* scope) { |
495 DCHECK_NOT_NULL(scope); | 463 DCHECK_NOT_NULL(scope); |
496 GetNestedScopeChain(isolate_, scope, GetSourcePosition()); | 464 int source_position = frame_inspector_->GetSourcePosition(); |
| 465 GetNestedScopeChain(isolate_, scope, source_position); |
497 } | 466 } |
498 | 467 |
499 void ScopeIterator::CollectNonLocals(ParseInfo* info, DeclarationScope* scope) { | 468 void ScopeIterator::CollectNonLocals(ParseInfo* info, DeclarationScope* scope) { |
500 DCHECK_NOT_NULL(scope); | 469 DCHECK_NOT_NULL(scope); |
501 DCHECK(non_locals_.is_null()); | 470 DCHECK(non_locals_.is_null()); |
502 non_locals_ = scope->CollectNonLocals(info, StringSet::New(isolate_)); | 471 non_locals_ = scope->CollectNonLocals(info, StringSet::New(isolate_)); |
503 } | 472 } |
504 | 473 |
505 | 474 |
506 MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() { | 475 MaybeHandle<JSObject> ScopeIterator::MaterializeScriptScope() { |
507 Handle<JSGlobalObject> global(CurrentContext()->global_object()); | 476 Handle<JSGlobalObject> global(CurrentContext()->global_object()); |
508 Handle<ScriptContextTable> script_contexts( | 477 Handle<ScriptContextTable> script_contexts( |
509 global->native_context()->script_context_table()); | 478 global->native_context()->script_context_table()); |
510 | 479 |
511 Handle<JSObject> script_scope = | 480 Handle<JSObject> script_scope = |
512 isolate_->factory()->NewJSObjectWithNullProto(); | 481 isolate_->factory()->NewJSObjectWithNullProto(); |
513 | 482 |
514 for (int context_index = 0; context_index < script_contexts->used(); | 483 for (int context_index = 0; context_index < script_contexts->used(); |
515 context_index++) { | 484 context_index++) { |
516 Handle<Context> context = | 485 Handle<Context> context = |
517 ScriptContextTable::GetContext(script_contexts, context_index); | 486 ScriptContextTable::GetContext(script_contexts, context_index); |
518 Handle<ScopeInfo> scope_info(context->scope_info()); | 487 Handle<ScopeInfo> scope_info(context->scope_info()); |
519 CopyContextLocalsToScopeObject(scope_info, context, script_scope); | 488 CopyContextLocalsToScopeObject(scope_info, context, script_scope); |
520 } | 489 } |
521 return script_scope; | 490 return script_scope; |
522 } | 491 } |
523 | 492 |
524 void ScopeIterator::MaterializeStackLocals(Handle<JSObject> local_scope, | |
525 Handle<ScopeInfo> scope_info) { | |
526 if (frame_inspector_) { | |
527 return frame_inspector_->MaterializeStackLocals(local_scope, scope_info); | |
528 } | |
529 | |
530 DCHECK(!generator_.is_null()); | |
531 // Fill all stack locals. | |
532 Handle<FixedArray> register_file(generator_->register_file()); | |
533 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | |
534 Handle<String> name = handle(scope_info->StackLocalName(i)); | |
535 if (ScopeInfo::VariableIsSynthetic(*name)) continue; | |
536 Handle<Object> value(register_file->get(scope_info->StackLocalIndex(i)), | |
537 isolate_); | |
538 // TODO(yangguo): We convert optimized out values to {undefined} when they | |
539 // are passed to the debugger. Eventually we should handle them somehow. | |
540 if (value->IsTheHole(isolate_) || value->IsOptimizedOut(isolate_)) { | |
541 DCHECK(!value.is_identical_to(isolate_->factory()->stale_register())); | |
542 value = isolate_->factory()->undefined_value(); | |
543 } | |
544 JSObject::SetOwnPropertyIgnoreAttributes(local_scope, name, value, NONE) | |
545 .Check(); | |
546 } | |
547 } | |
548 | 493 |
549 MaybeHandle<JSObject> ScopeIterator::MaterializeLocalScope() { | 494 MaybeHandle<JSObject> ScopeIterator::MaterializeLocalScope() { |
550 Handle<JSFunction> function(GetFunction()); | 495 Handle<JSFunction> function = GetFunction(); |
| 496 |
| 497 Handle<JSObject> local_scope = |
| 498 isolate_->factory()->NewJSObjectWithNullProto(); |
| 499 frame_inspector_->MaterializeStackLocals(local_scope, function); |
| 500 |
| 501 Handle<Context> frame_context = |
| 502 Handle<Context>::cast(frame_inspector_->GetContext()); |
| 503 |
| 504 HandleScope scope(isolate_); |
551 Handle<SharedFunctionInfo> shared(function->shared()); | 505 Handle<SharedFunctionInfo> shared(function->shared()); |
552 Handle<ScopeInfo> scope_info(shared->scope_info()); | 506 Handle<ScopeInfo> scope_info(shared->scope_info()); |
553 | 507 |
554 Handle<JSObject> local_scope = | |
555 isolate_->factory()->NewJSObjectWithNullProto(); | |
556 MaterializeStackLocals(local_scope, scope_info); | |
557 | |
558 Handle<Context> frame_context = GetContext(); | |
559 | |
560 if (!scope_info->HasContext()) return local_scope; | 508 if (!scope_info->HasContext()) return local_scope; |
561 | 509 |
562 // Fill all context locals. | 510 // Fill all context locals. |
563 Handle<Context> function_context(frame_context->closure_context()); | 511 Handle<Context> function_context(frame_context->closure_context()); |
564 CopyContextLocalsToScopeObject(scope_info, function_context, local_scope); | 512 CopyContextLocalsToScopeObject(scope_info, function_context, local_scope); |
565 | 513 |
566 // Finally copy any properties from the function context extension. | 514 // Finally copy any properties from the function context extension. |
567 // These will be variables introduced by eval. | 515 // These will be variables introduced by eval. |
568 if (function_context->closure() == *function && | 516 if (function_context->closure() == *function && |
569 !function_context->IsNativeContext()) { | 517 !function_context->IsNativeContext()) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 578 |
631 // Create a plain JSObject which materializes the block scope for the specified | 579 // Create a plain JSObject which materializes the block scope for the specified |
632 // block context. | 580 // block context. |
633 Handle<JSObject> ScopeIterator::MaterializeInnerScope() { | 581 Handle<JSObject> ScopeIterator::MaterializeInnerScope() { |
634 Handle<JSObject> inner_scope = | 582 Handle<JSObject> inner_scope = |
635 isolate_->factory()->NewJSObjectWithNullProto(); | 583 isolate_->factory()->NewJSObjectWithNullProto(); |
636 | 584 |
637 Handle<Context> context = Handle<Context>::null(); | 585 Handle<Context> context = Handle<Context>::null(); |
638 if (!nested_scope_chain_.is_empty()) { | 586 if (!nested_scope_chain_.is_empty()) { |
639 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; | 587 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; |
640 MaterializeStackLocals(inner_scope, scope_info); | 588 frame_inspector_->MaterializeStackLocals(inner_scope, scope_info); |
641 if (scope_info->HasContext()) context = CurrentContext(); | 589 if (scope_info->HasContext()) context = CurrentContext(); |
642 } else { | 590 } else { |
643 context = CurrentContext(); | 591 context = CurrentContext(); |
644 } | 592 } |
645 | 593 |
646 if (!context.is_null()) { | 594 if (!context.is_null()) { |
647 // Fill all context locals. | 595 // Fill all context locals. |
648 CopyContextLocalsToScopeObject(CurrentScopeInfo(), context, inner_scope); | 596 CopyContextLocalsToScopeObject(CurrentScopeInfo(), context, inner_scope); |
649 CopyContextExtensionToScopeObject(context, inner_scope, | 597 CopyContextExtensionToScopeObject(context, inner_scope, |
650 KeyCollectionMode::kOwnOnly); | 598 KeyCollectionMode::kOwnOnly); |
651 } | 599 } |
652 return inner_scope; | 600 return inner_scope; |
653 } | 601 } |
654 | 602 |
655 | 603 |
656 // Create a plain JSObject which materializes the module scope for the specified | 604 // Create a plain JSObject which materializes the module scope for the specified |
657 // module context. | 605 // module context. |
658 MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() { | 606 MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() { |
659 Handle<Context> context = CurrentContext(); | 607 Handle<Context> context = CurrentContext(); |
660 DCHECK(context->IsModuleContext()); | 608 DCHECK(context->IsModuleContext()); |
661 Handle<ScopeInfo> scope_info(context->scope_info()); | 609 Handle<ScopeInfo> scope_info(context->scope_info()); |
662 Handle<JSObject> module_scope = | 610 Handle<JSObject> module_scope = |
663 isolate_->factory()->NewJSObjectWithNullProto(); | 611 isolate_->factory()->NewJSObjectWithNullProto(); |
664 CopyContextLocalsToScopeObject(scope_info, context, module_scope); | 612 CopyContextLocalsToScopeObject(scope_info, context, module_scope); |
665 CopyModuleVarsToScopeObject(scope_info, context, module_scope); | 613 CopyModuleVarsToScopeObject(scope_info, context, module_scope); |
666 return module_scope; | 614 return module_scope; |
667 } | 615 } |
668 | 616 |
669 bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info, | 617 bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info, |
| 618 JavaScriptFrame* frame, |
670 Handle<String> parameter_name, | 619 Handle<String> parameter_name, |
671 Handle<Object> new_value) { | 620 Handle<Object> new_value) { |
672 // Setting stack locals of optimized frames is not supported. | 621 // Setting stack locals of optimized frames is not supported. |
| 622 if (frame->is_optimized()) return false; |
673 HandleScope scope(isolate_); | 623 HandleScope scope(isolate_); |
674 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 624 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
675 if (String::Equals(handle(scope_info->ParameterName(i)), parameter_name)) { | 625 if (String::Equals(handle(scope_info->ParameterName(i)), parameter_name)) { |
676 // Suspended generators should not get here because all parameters should | |
677 // be context-allocated. | |
678 DCHECK_NOT_NULL(frame_inspector_); | |
679 JavaScriptFrame* frame = GetFrame(); | |
680 if (frame->is_optimized()) { | |
681 return false; | |
682 } | |
683 frame->SetParameterValue(i, *new_value); | 626 frame->SetParameterValue(i, *new_value); |
684 return true; | 627 return true; |
685 } | 628 } |
686 } | 629 } |
687 return false; | 630 return false; |
688 } | 631 } |
689 | 632 |
690 bool ScopeIterator::SetStackVariableValue(Handle<ScopeInfo> scope_info, | 633 bool ScopeIterator::SetStackVariableValue(Handle<ScopeInfo> scope_info, |
691 Handle<String> variable_name, | 634 Handle<String> variable_name, |
692 Handle<Object> new_value) { | 635 Handle<Object> new_value) { |
693 // Setting stack locals of optimized frames is not supported. Suspended | 636 if (frame_inspector_ == nullptr) return false; |
694 // generators are supported. | 637 JavaScriptFrame* frame = GetFrame(); |
| 638 // Setting stack locals of optimized frames is not supported. |
| 639 if (frame->is_optimized()) return false; |
695 HandleScope scope(isolate_); | 640 HandleScope scope(isolate_); |
696 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 641 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
697 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { | 642 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { |
698 int stack_local_index = scope_info->StackLocalIndex(i); | 643 frame->SetExpression(scope_info->StackLocalIndex(i), *new_value); |
699 if (frame_inspector_ != nullptr) { | |
700 // Set the variable on the stack. | |
701 JavaScriptFrame* frame = GetFrame(); | |
702 if (frame->is_optimized()) return false; | |
703 frame->SetExpression(stack_local_index, *new_value); | |
704 } else { | |
705 // Set the variable in the suspended generator. | |
706 DCHECK(!generator_.is_null()); | |
707 Handle<FixedArray> register_file(generator_->register_file()); | |
708 DCHECK_LT(stack_local_index, register_file->length()); | |
709 register_file->set(stack_local_index, *new_value); | |
710 } | |
711 return true; | 644 return true; |
712 } | 645 } |
713 } | 646 } |
714 return false; | 647 return false; |
715 } | 648 } |
716 | 649 |
717 bool ScopeIterator::SetContextVariableValue(Handle<ScopeInfo> scope_info, | 650 bool ScopeIterator::SetContextVariableValue(Handle<ScopeInfo> scope_info, |
718 Handle<Context> context, | 651 Handle<Context> context, |
719 Handle<String> variable_name, | 652 Handle<String> variable_name, |
720 Handle<Object> new_value) { | 653 Handle<Object> new_value) { |
(...skipping 22 matching lines...) Expand all Loading... |
743 .Check(); | 676 .Check(); |
744 return true; | 677 return true; |
745 } | 678 } |
746 } | 679 } |
747 | 680 |
748 return false; | 681 return false; |
749 } | 682 } |
750 | 683 |
751 bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, | 684 bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, |
752 Handle<Object> new_value) { | 685 Handle<Object> new_value) { |
753 Handle<ScopeInfo> scope_info(GetFunction()->shared()->scope_info()); | 686 JavaScriptFrame* frame = GetFrame(); |
| 687 Handle<ScopeInfo> scope_info(frame->function()->shared()->scope_info()); |
754 | 688 |
755 // Parameter might be shadowed in context. Don't stop here. | 689 // Parameter might be shadowed in context. Don't stop here. |
756 bool result = SetParameterValue(scope_info, variable_name, new_value); | 690 bool result = SetParameterValue(scope_info, frame, variable_name, new_value); |
757 | 691 |
758 // Stack locals. | 692 // Stack locals. |
759 if (SetStackVariableValue(scope_info, variable_name, new_value)) { | 693 if (SetStackVariableValue(scope_info, variable_name, new_value)) { |
760 return true; | 694 return true; |
761 } | 695 } |
762 | 696 |
763 if (scope_info->HasContext() && | 697 if (scope_info->HasContext() && |
764 SetContextVariableValue(scope_info, CurrentContext(), variable_name, | 698 SetContextVariableValue(scope_info, CurrentContext(), variable_name, |
765 new_value)) { | 699 new_value)) { |
766 return true; | 700 return true; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 JSObject::SetOwnPropertyIgnoreAttributes(scope_object, key, value, NONE) | 832 JSObject::SetOwnPropertyIgnoreAttributes(scope_object, key, value, NONE) |
899 .Check(); | 833 .Check(); |
900 } | 834 } |
901 } | 835 } |
902 | 836 |
903 void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, | 837 void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, |
904 int position) { | 838 int position) { |
905 if (scope->is_function_scope()) { | 839 if (scope->is_function_scope()) { |
906 // Do not collect scopes of nested inner functions inside the current one. | 840 // Do not collect scopes of nested inner functions inside the current one. |
907 // Nested arrow functions could have the same end positions. | 841 // Nested arrow functions could have the same end positions. |
908 Handle<JSFunction> function = GetFunction(); | 842 Handle<JSFunction> function = frame_inspector_->GetFunction(); |
909 if (scope->start_position() > function->shared()->start_position() && | 843 if (scope->start_position() > function->shared()->start_position() && |
910 scope->end_position() <= function->shared()->end_position()) { | 844 scope->end_position() <= function->shared()->end_position()) { |
911 return; | 845 return; |
912 } | 846 } |
913 } | 847 } |
914 if (scope->is_hidden()) { | 848 if (scope->is_hidden()) { |
915 // We need to add this chain element in case the scope has a context | 849 // We need to add this chain element in case the scope has a context |
916 // associated. We need to keep the scope chain and context chain in sync. | 850 // associated. We need to keep the scope chain and context chain in sync. |
917 nested_scope_chain_.Add(ExtendedScopeInfo(scope->scope_info())); | 851 nested_scope_chain_.Add(ExtendedScopeInfo(scope->scope_info())); |
918 } else { | 852 } else { |
919 nested_scope_chain_.Add(ExtendedScopeInfo( | 853 nested_scope_chain_.Add(ExtendedScopeInfo( |
920 scope->scope_info(), scope->start_position(), scope->end_position())); | 854 scope->scope_info(), scope->start_position(), scope->end_position())); |
921 } | 855 } |
922 for (Scope* inner_scope = scope->inner_scope(); inner_scope != nullptr; | 856 for (Scope* inner_scope = scope->inner_scope(); inner_scope != nullptr; |
923 inner_scope = inner_scope->sibling()) { | 857 inner_scope = inner_scope->sibling()) { |
924 int beg_pos = inner_scope->start_position(); | 858 int beg_pos = inner_scope->start_position(); |
925 int end_pos = inner_scope->end_position(); | 859 int end_pos = inner_scope->end_position(); |
926 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); | 860 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); |
927 if (beg_pos <= position && position < end_pos) { | 861 if (beg_pos <= position && position < end_pos) { |
928 GetNestedScopeChain(isolate, inner_scope, position); | 862 GetNestedScopeChain(isolate, inner_scope, position); |
929 return; | 863 return; |
930 } | 864 } |
931 } | 865 } |
932 } | 866 } |
933 | 867 |
934 } // namespace internal | 868 } // namespace internal |
935 } // namespace v8 | 869 } // namespace v8 |
OLD | NEW |