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 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 // module. | 600 // module. |
601 Handle<JSObject> module_scope = | 601 Handle<JSObject> module_scope = |
602 isolate_->factory()->NewJSObjectWithNullProto(); | 602 isolate_->factory()->NewJSObjectWithNullProto(); |
603 | 603 |
604 // Fill all context locals. | 604 // Fill all context locals. |
605 CopyContextLocalsToScopeObject(scope_info, context, module_scope); | 605 CopyContextLocalsToScopeObject(scope_info, context, module_scope); |
606 | 606 |
607 return module_scope; | 607 return module_scope; |
608 } | 608 } |
609 | 609 |
| 610 bool ScopeIterator::SetParameterValue(Handle<ScopeInfo> scope_info, |
| 611 JavaScriptFrame* frame, |
| 612 Handle<String> parameter_name, |
| 613 Handle<Object> new_value) { |
| 614 // Setting stack locals of optimized frames is not supported. |
| 615 if (frame->is_optimized()) return false; |
| 616 HandleScope scope(isolate_); |
| 617 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
| 618 if (String::Equals(handle(scope_info->ParameterName(i)), parameter_name)) { |
| 619 frame->SetParameterValue(i, *new_value); |
| 620 return true; |
| 621 } |
| 622 } |
| 623 return false; |
| 624 } |
610 | 625 |
611 // Set the context local variable value. | 626 bool ScopeIterator::SetStackVariableValue(Handle<ScopeInfo> scope_info, |
612 bool ScopeIterator::SetContextLocalValue(Handle<ScopeInfo> scope_info, | 627 JavaScriptFrame* frame, |
613 Handle<Context> context, | 628 Handle<String> variable_name, |
614 Handle<String> variable_name, | 629 Handle<Object> new_value) { |
615 Handle<Object> new_value) { | 630 // Setting stack locals of optimized frames is not supported. |
| 631 if (frame->is_optimized()) return false; |
| 632 HandleScope scope(isolate_); |
| 633 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
| 634 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { |
| 635 frame->SetExpression(scope_info->StackLocalIndex(i), *new_value); |
| 636 return true; |
| 637 } |
| 638 } |
| 639 return false; |
| 640 } |
| 641 |
| 642 bool ScopeIterator::SetContextVariableValue(Handle<ScopeInfo> scope_info, |
| 643 Handle<Context> context, |
| 644 Handle<String> variable_name, |
| 645 Handle<Object> new_value) { |
| 646 HandleScope scope(isolate_); |
616 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { | 647 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
617 Handle<String> next_name(scope_info->ContextLocalName(i)); | 648 Handle<String> next_name(scope_info->ContextLocalName(i)); |
618 if (String::Equals(variable_name, next_name)) { | 649 if (String::Equals(variable_name, next_name)) { |
619 VariableMode mode; | 650 VariableMode mode; |
620 InitializationFlag init_flag; | 651 InitializationFlag init_flag; |
621 MaybeAssignedFlag maybe_assigned_flag; | 652 MaybeAssignedFlag maybe_assigned_flag; |
622 int context_index = ScopeInfo::ContextSlotIndex( | 653 int context_index = ScopeInfo::ContextSlotIndex( |
623 scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag); | 654 scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag); |
624 context->set(context_index, *new_value); | 655 context->set(context_index, *new_value); |
625 return true; | 656 return true; |
626 } | 657 } |
627 } | 658 } |
628 | 659 |
629 return false; | |
630 } | |
631 | |
632 | |
633 bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, | |
634 Handle<Object> new_value) { | |
635 JavaScriptFrame* frame = GetFrame(); | |
636 // Optimized frames are not supported. | |
637 if (frame->is_optimized()) return false; | |
638 | |
639 Handle<JSFunction> function(frame->function()); | |
640 Handle<SharedFunctionInfo> shared(function->shared()); | |
641 Handle<ScopeInfo> scope_info(shared->scope_info()); | |
642 | |
643 bool default_result = false; | |
644 | |
645 // Parameters. | |
646 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | |
647 HandleScope scope(isolate_); | |
648 if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) { | |
649 frame->SetParameterValue(i, *new_value); | |
650 // Argument might be shadowed in heap context, don't stop here. | |
651 default_result = true; | |
652 } | |
653 } | |
654 | |
655 // Stack locals. | |
656 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | |
657 HandleScope scope(isolate_); | |
658 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { | |
659 frame->SetExpression(scope_info->StackLocalIndex(i), *new_value); | |
660 return true; | |
661 } | |
662 } | |
663 | |
664 if (scope_info->HasContext()) { | |
665 // Context locals. | |
666 Handle<Context> frame_context(Context::cast(frame->context())); | |
667 Handle<Context> function_context(frame_context->declaration_context()); | |
668 if (SetContextLocalValue(scope_info, function_context, variable_name, | |
669 new_value)) { | |
670 return true; | |
671 } | |
672 | |
673 // Function context extension. These are variables introduced by eval. | |
674 if (function_context->closure() == *function) { | |
675 if (function_context->has_extension() && | |
676 !function_context->IsNativeContext()) { | |
677 Handle<JSObject> ext(function_context->extension_object()); | |
678 | |
679 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); | |
680 DCHECK(maybe.IsJust()); | |
681 if (maybe.FromJust()) { | |
682 // We don't expect this to do anything except replacing | |
683 // property value. | |
684 Runtime::SetObjectProperty(isolate_, ext, variable_name, new_value, | |
685 SLOPPY) | |
686 .Assert(); | |
687 return true; | |
688 } | |
689 } | |
690 } | |
691 } | |
692 | |
693 return default_result; | |
694 } | |
695 | |
696 | |
697 bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name, | |
698 Handle<Object> new_value) { | |
699 Handle<ScopeInfo> scope_info = CurrentScopeInfo(); | |
700 JavaScriptFrame* frame = GetFrame(); | |
701 | |
702 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | |
703 HandleScope scope(isolate_); | |
704 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { | |
705 frame->SetExpression(scope_info->StackLocalIndex(i), *new_value); | |
706 return true; | |
707 } | |
708 } | |
709 | |
710 if (HasContext()) { | |
711 Handle<Context> context = CurrentContext(); | |
712 if (SetContextLocalValue(scope_info, context, variable_name, new_value)) { | |
713 return true; | |
714 } | |
715 | |
716 Handle<JSObject> ext(context->extension_object(), isolate_); | |
717 if (!ext.is_null()) { | |
718 Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name); | |
719 DCHECK(maybe.IsJust()); | |
720 if (maybe.FromJust()) { | |
721 // We don't expect this to do anything except replacing property value. | |
722 JSObject::SetOwnPropertyIgnoreAttributes(ext, variable_name, new_value, | |
723 NONE) | |
724 .Check(); | |
725 return true; | |
726 } | |
727 } | |
728 } | |
729 | |
730 return false; | |
731 } | |
732 | |
733 | |
734 // This method copies structure of MaterializeClosure method above. | |
735 bool ScopeIterator::SetClosureVariableValue(Handle<String> variable_name, | |
736 Handle<Object> new_value) { | |
737 Handle<Context> context = CurrentContext(); | |
738 DCHECK(context->IsFunctionContext()); | |
739 | |
740 // Context locals to the context extension. | |
741 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | |
742 Handle<ScopeInfo> scope_info(shared->scope_info()); | |
743 if (SetContextLocalValue(scope_info, context, variable_name, new_value)) { | |
744 return true; | |
745 } | |
746 | |
747 // Properties from the function context extension. This will | |
748 // be variables introduced by eval. | |
749 if (context->has_extension()) { | 660 if (context->has_extension()) { |
750 Handle<JSObject> ext(JSObject::cast(context->extension_object())); | 661 Handle<JSObject> ext(context->extension_object()); |
751 Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name); | 662 Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name); |
752 DCHECK(maybe.IsJust()); | 663 DCHECK(maybe.IsJust()); |
753 if (maybe.FromJust()) { | 664 if (maybe.FromJust()) { |
754 // We don't expect this to do anything except replacing property value. | 665 // We don't expect this to do anything except replacing property value. |
755 JSObject::SetOwnPropertyIgnoreAttributes(ext, variable_name, new_value, | 666 JSObject::SetOwnPropertyIgnoreAttributes(ext, variable_name, new_value, |
756 NONE) | 667 NONE) |
757 .Check(); | 668 .Check(); |
758 return true; | 669 return true; |
759 } | 670 } |
760 } | 671 } |
761 | 672 |
762 return false; | 673 return false; |
763 } | 674 } |
764 | 675 |
| 676 bool ScopeIterator::SetLocalVariableValue(Handle<String> variable_name, |
| 677 Handle<Object> new_value) { |
| 678 JavaScriptFrame* frame = GetFrame(); |
| 679 Handle<ScopeInfo> scope_info(frame->function()->shared()->scope_info()); |
| 680 |
| 681 // Parameter might be shadowed in context. Don't stop here. |
| 682 bool result = SetParameterValue(scope_info, frame, variable_name, new_value); |
| 683 |
| 684 // Stack locals. |
| 685 if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) { |
| 686 return true; |
| 687 } |
| 688 |
| 689 if (scope_info->HasContext() && |
| 690 SetContextVariableValue(scope_info, CurrentContext(), variable_name, |
| 691 new_value)) { |
| 692 return true; |
| 693 } |
| 694 |
| 695 return result; |
| 696 } |
| 697 |
| 698 bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name, |
| 699 Handle<Object> new_value) { |
| 700 Handle<ScopeInfo> scope_info = CurrentScopeInfo(); |
| 701 JavaScriptFrame* frame = GetFrame(); |
| 702 |
| 703 // Setting stack locals of optimized frames is not supported. |
| 704 if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) { |
| 705 return true; |
| 706 } |
| 707 |
| 708 if (HasContext() && SetContextVariableValue(scope_info, CurrentContext(), |
| 709 variable_name, new_value)) { |
| 710 return true; |
| 711 } |
| 712 |
| 713 return false; |
| 714 } |
| 715 |
| 716 // This method copies structure of MaterializeClosure method above. |
| 717 bool ScopeIterator::SetClosureVariableValue(Handle<String> variable_name, |
| 718 Handle<Object> new_value) { |
| 719 DCHECK(CurrentContext()->IsFunctionContext()); |
| 720 return SetContextVariableValue(CurrentScopeInfo(), CurrentContext(), |
| 721 variable_name, new_value); |
| 722 } |
765 | 723 |
766 bool ScopeIterator::SetScriptVariableValue(Handle<String> variable_name, | 724 bool ScopeIterator::SetScriptVariableValue(Handle<String> variable_name, |
767 Handle<Object> new_value) { | 725 Handle<Object> new_value) { |
768 Handle<Context> context = CurrentContext(); | 726 Handle<Context> context = CurrentContext(); |
769 Handle<ScriptContextTable> script_contexts( | 727 Handle<ScriptContextTable> script_contexts( |
770 context->global_object()->native_context()->script_context_table()); | 728 context->global_object()->native_context()->script_context_table()); |
771 ScriptContextTable::LookupResult lookup_result; | 729 ScriptContextTable::LookupResult lookup_result; |
772 if (ScriptContextTable::Lookup(script_contexts, variable_name, | 730 if (ScriptContextTable::Lookup(script_contexts, variable_name, |
773 &lookup_result)) { | 731 &lookup_result)) { |
774 Handle<Context> script_context = ScriptContextTable::GetContext( | 732 Handle<Context> script_context = ScriptContextTable::GetContext( |
775 script_contexts, lookup_result.context_index); | 733 script_contexts, lookup_result.context_index); |
776 script_context->set(lookup_result.slot_index, *new_value); | 734 script_context->set(lookup_result.slot_index, *new_value); |
777 return true; | 735 return true; |
778 } | 736 } |
779 | 737 |
780 return false; | 738 return false; |
781 } | 739 } |
782 | 740 |
783 | |
784 bool ScopeIterator::SetCatchVariableValue(Handle<String> variable_name, | 741 bool ScopeIterator::SetCatchVariableValue(Handle<String> variable_name, |
785 Handle<Object> new_value) { | 742 Handle<Object> new_value) { |
786 Handle<Context> context = CurrentContext(); | 743 Handle<Context> context = CurrentContext(); |
787 DCHECK(context->IsCatchContext()); | 744 DCHECK(context->IsCatchContext()); |
788 Handle<String> name(context->catch_name()); | 745 Handle<String> name(context->catch_name()); |
789 if (!String::Equals(name, variable_name)) { | 746 if (!String::Equals(name, variable_name)) { |
790 return false; | 747 return false; |
791 } | 748 } |
792 context->set(Context::THROWN_OBJECT_INDEX, *new_value); | 749 context->set(Context::THROWN_OBJECT_INDEX, *new_value); |
793 return true; | 750 return true; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); | 808 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); |
852 if (beg_pos <= position && position < end_pos) { | 809 if (beg_pos <= position && position < end_pos) { |
853 GetNestedScopeChain(isolate, inner_scope, position); | 810 GetNestedScopeChain(isolate, inner_scope, position); |
854 return; | 811 return; |
855 } | 812 } |
856 } | 813 } |
857 } | 814 } |
858 | 815 |
859 } // namespace internal | 816 } // namespace internal |
860 } // namespace v8 | 817 } // namespace v8 |
OLD | NEW |