OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/isolate.h" | 5 #include "src/isolate.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <fstream> // NOLINT(readability/streams) | 9 #include <fstream> // NOLINT(readability/streams) |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 JSReceiver::GetDataProperty(error_object, key_detailed); | 607 JSReceiver::GetDataProperty(error_object, key_detailed); |
608 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); | 608 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); |
609 return Handle<JSArray>(); | 609 return Handle<JSArray>(); |
610 } | 610 } |
611 | 611 |
612 | 612 |
613 class CaptureStackTraceHelper { | 613 class CaptureStackTraceHelper { |
614 public: | 614 public: |
615 CaptureStackTraceHelper(Isolate* isolate, | 615 CaptureStackTraceHelper(Isolate* isolate, |
616 StackTrace::StackTraceOptions options) | 616 StackTrace::StackTraceOptions options) |
617 : isolate_(isolate) { | 617 : isolate_(isolate), options_(options) {} |
618 if (options & StackTrace::kColumnOffset) { | |
619 column_key_ = | |
620 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column")); | |
621 } | |
622 if (options & StackTrace::kLineNumber) { | |
623 line_key_ = | |
624 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber")); | |
625 } | |
626 if (options & StackTrace::kScriptId) { | |
627 script_id_key_ = | |
628 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId")); | |
629 } | |
630 if (options & StackTrace::kScriptName) { | |
631 script_name_key_ = | |
632 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName")); | |
633 } | |
634 if (options & StackTrace::kScriptNameOrSourceURL) { | |
635 script_name_or_source_url_key_ = factory()->InternalizeOneByteString( | |
636 STATIC_CHAR_VECTOR("scriptNameOrSourceURL")); | |
637 } | |
638 if (options & StackTrace::kFunctionName) { | |
639 function_key_ = factory()->InternalizeOneByteString( | |
640 STATIC_CHAR_VECTOR("functionName")); | |
641 } | |
642 if (options & StackTrace::kIsEval) { | |
643 eval_key_ = | |
644 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); | |
645 } | |
646 if (options & StackTrace::kIsConstructor) { | |
647 constructor_key_ = factory()->InternalizeOneByteString( | |
648 STATIC_CHAR_VECTOR("isConstructor")); | |
649 } | |
650 } | |
651 | 618 |
652 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { | 619 Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) { |
653 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); | 620 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); |
654 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); | 621 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); |
655 UNREACHABLE(); | 622 UNREACHABLE(); |
656 return Handle<JSObject>::null(); | 623 return factory()->NewStackFrameInfo(); |
657 } | 624 } |
658 | 625 |
659 Handle<JSObject> NewStackFrameObject( | 626 Handle<StackFrameInfo> NewStackFrameObject( |
660 const FrameSummary::JavaScriptFrameSummary& summ) { | 627 const FrameSummary::JavaScriptFrameSummary& summ) { |
661 Handle<JSObject> stack_frame = | 628 Handle<StackFrameInfo> frame = factory()->NewStackFrameInfo(); |
662 factory()->NewJSObject(isolate_->object_function()); | |
663 Handle<Script> script = Handle<Script>::cast(summ.script()); | 629 Handle<Script> script = Handle<Script>::cast(summ.script()); |
664 | 630 if (options_ & StackTrace::kLineNumber) { |
665 if (!line_key_.is_null()) { | |
666 Script::PositionInfo info; | 631 Script::PositionInfo info; |
667 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), | 632 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), |
668 &info, Script::WITH_OFFSET); | 633 &info, Script::WITH_OFFSET); |
Yang
2017/04/03 07:58:40
Getting position info is fairly expensive. We can
kozy
2017/04/03 14:54:56
Thanks, I'll upload separate CLfor this because cu
| |
669 | 634 if (valid_pos) { |
670 if (!column_key_.is_null() && valid_pos) { | 635 frame->set_line_number(info.line + 1); |
671 JSObject::AddProperty(stack_frame, column_key_, | 636 if (options_ & StackTrace::kColumnOffset) { |
672 handle(Smi::FromInt(info.column + 1), isolate_), | 637 frame->set_column_number(info.column + 1); |
673 NONE); | 638 } |
674 } | 639 } |
675 JSObject::AddProperty(stack_frame, line_key_, | |
676 handle(Smi::FromInt(info.line + 1), isolate_), | |
677 NONE); | |
678 } | 640 } |
679 | 641 |
680 if (!script_id_key_.is_null()) { | 642 if (options_ & StackTrace::kScriptId) frame->set_script_id(script->id()); |
681 JSObject::AddProperty(stack_frame, script_id_key_, | 643 if (options_ & StackTrace::kScriptName) { |
682 handle(Smi::FromInt(script->id()), isolate_), NONE); | 644 frame->set_script_name(script->name()); |
683 } | 645 } |
684 | 646 if (options_ & StackTrace::kScriptNameOrSourceURL) { |
685 if (!script_name_key_.is_null()) { | 647 frame->set_script_name_or_source_url(script->GetNameOrSourceURL()); |
686 JSObject::AddProperty(stack_frame, script_name_key_, | |
687 handle(script->name(), isolate_), NONE); | |
688 } | 648 } |
689 | 649 if (options_ & StackTrace::kIsEval) { |
690 if (!script_name_or_source_url_key_.is_null()) { | 650 frame->set_is_eval(script->compilation_type() == |
691 Handle<Object> result(script->GetNameOrSourceURL(), isolate_); | 651 Script::COMPILATION_TYPE_EVAL); |
692 JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result, | |
693 NONE); | |
694 } | 652 } |
695 | 653 if (options_ & StackTrace::kFunctionName) { |
696 if (!eval_key_.is_null()) { | 654 frame->set_function_name(*summ.FunctionName()); |
697 Handle<Object> is_eval = factory()->ToBoolean( | |
698 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); | |
699 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); | |
700 } | 655 } |
701 | 656 if (options_ & StackTrace::kIsConstructor) { |
702 if (!function_key_.is_null()) { | 657 frame->set_is_constructor(summ.is_constructor()); |
703 Handle<String> fun_name = summ.FunctionName(); | |
704 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | |
705 } | 658 } |
706 | 659 return frame; |
707 if (!constructor_key_.is_null()) { | |
708 Handle<Object> is_constructor_obj = | |
709 factory()->ToBoolean(summ.is_constructor()); | |
710 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj, | |
711 NONE); | |
712 } | |
713 return stack_frame; | |
714 } | 660 } |
715 | 661 |
716 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { | 662 Handle<StackFrameInfo> NewStackFrameObject( |
717 Handle<JSObject> stack_frame = | 663 const FrameSummary::WasmFrameSummary& summ) { |
718 factory()->NewJSObject(isolate_->object_function()); | 664 Handle<StackFrameInfo> info = factory()->NewStackFrameInfo(); |
719 Handle<JSFunction> fun = handle(frame->function(), isolate_); | |
720 if (!function_key_.is_null()) { | |
721 Handle<Object> fun_name = JSFunction::GetDebugName(fun); | |
722 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | |
723 } | |
724 | 665 |
725 // We don't have a script and hence cannot set line and col positions. | 666 if (options_ & StackTrace::kFunctionName) { |
726 DCHECK(!fun->shared()->script()->IsScript()); | |
727 | |
728 return stack_frame; | |
729 } | |
730 | |
731 Handle<JSObject> NewStackFrameObject( | |
732 const FrameSummary::WasmFrameSummary& summ) { | |
733 Handle<JSObject> stack_frame = | |
734 factory()->NewJSObject(isolate_->object_function()); | |
735 | |
736 if (!function_key_.is_null()) { | |
737 Handle<WasmCompiledModule> compiled_module( | 667 Handle<WasmCompiledModule> compiled_module( |
738 summ.wasm_instance()->compiled_module(), isolate_); | 668 summ.wasm_instance()->compiled_module(), isolate_); |
739 Handle<String> name = WasmCompiledModule::GetFunctionName( | 669 Handle<String> name = WasmCompiledModule::GetFunctionName( |
740 isolate_, compiled_module, summ.function_index()); | 670 isolate_, compiled_module, summ.function_index()); |
741 JSObject::AddProperty(stack_frame, function_key_, name, NONE); | 671 info->set_function_name(*name); |
742 } | 672 } |
743 // Encode the function index as line number (1-based). | 673 // Encode the function index as line number (1-based). |
744 if (!line_key_.is_null()) { | 674 if (options_ & StackTrace::kLineNumber) { |
745 JSObject::AddProperty( | 675 info->set_line_number(summ.function_index() + 1); |
746 stack_frame, line_key_, | |
747 isolate_->factory()->NewNumberFromInt(summ.function_index() + 1), | |
748 NONE); | |
749 } | 676 } |
750 // Encode the byte offset as column (1-based). | 677 // Encode the byte offset as column (1-based). |
751 if (!column_key_.is_null()) { | 678 if (options_ & StackTrace::kColumnOffset) { |
752 int position = summ.byte_offset(); | 679 int position = summ.byte_offset(); |
753 // Make position 1-based. | 680 // Make position 1-based. |
754 if (position >= 0) ++position; | 681 if (position >= 0) ++position; |
755 JSObject::AddProperty(stack_frame, column_key_, | 682 info->set_column_number(position); |
756 isolate_->factory()->NewNumberFromInt(position), | |
757 NONE); | |
758 } | 683 } |
759 if (!script_id_key_.is_null()) { | 684 if (options_ & StackTrace::kScriptId) { |
760 int script_id = summ.script()->id(); | 685 info->set_script_id(summ.script()->id()); |
761 JSObject::AddProperty(stack_frame, script_id_key_, | |
762 handle(Smi::FromInt(script_id), isolate_), NONE); | |
763 } | 686 } |
764 | 687 return info; |
765 return stack_frame; | |
766 } | 688 } |
767 | 689 |
768 private: | 690 private: |
769 inline Factory* factory() { return isolate_->factory(); } | 691 inline Factory* factory() { return isolate_->factory(); } |
770 | 692 |
771 Isolate* isolate_; | 693 Isolate* isolate_; |
772 Handle<String> column_key_; | 694 StackTrace::StackTraceOptions options_; |
773 Handle<String> line_key_; | |
774 Handle<String> script_id_key_; | |
775 Handle<String> script_name_key_; | |
776 Handle<String> script_name_or_source_url_key_; | |
777 Handle<String> function_key_; | |
778 Handle<String> eval_key_; | |
779 Handle<String> constructor_key_; | |
780 }; | 695 }; |
781 | 696 |
782 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 697 Handle<JSArray> Isolate::CaptureCurrentStackTrace( |
783 int frame_limit, StackTrace::StackTraceOptions options) { | 698 int frame_limit, StackTrace::StackTraceOptions options) { |
784 DisallowJavascriptExecution no_js(this); | 699 DisallowJavascriptExecution no_js(this); |
785 CaptureStackTraceHelper helper(this, options); | 700 CaptureStackTraceHelper helper(this, options); |
786 | 701 |
787 // Ensure no negative values. | 702 // Ensure no negative values. |
788 int limit = Max(frame_limit, 0); | 703 int limit = Max(frame_limit, 0); |
789 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 704 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
790 Handle<FixedArray> stack_trace_elems( | 705 Handle<FixedArray> stack_trace_elems( |
791 FixedArray::cast(stack_trace->elements()), this); | 706 FixedArray::cast(stack_trace->elements()), this); |
792 | 707 |
793 int frames_seen = 0; | 708 int frames_seen = 0; |
794 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 709 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
795 it.Advance()) { | 710 it.Advance()) { |
796 StandardFrame* frame = it.frame(); | 711 StandardFrame* frame = it.frame(); |
797 // Set initial size to the maximum inlining level + 1 for the outermost | 712 // Set initial size to the maximum inlining level + 1 for the outermost |
798 // function. | 713 // function. |
799 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 714 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
800 frame->Summarize(&frames); | 715 frame->Summarize(&frames); |
801 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 716 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
802 // Filter frames from other security contexts. | 717 // Filter frames from other security contexts. |
803 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 718 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
804 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) | 719 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
805 continue; | 720 continue; |
806 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); | 721 Handle<StackFrameInfo> new_frame_obj = |
722 helper.NewStackFrameObject(frames[i]); | |
807 stack_trace_elems->set(frames_seen, *new_frame_obj); | 723 stack_trace_elems->set(frames_seen, *new_frame_obj); |
808 frames_seen++; | 724 frames_seen++; |
809 } | 725 } |
810 } | 726 } |
811 | 727 |
812 stack_trace->set_length(Smi::FromInt(frames_seen)); | 728 stack_trace->set_length(Smi::FromInt(frames_seen)); |
813 return stack_trace; | 729 return stack_trace; |
814 } | 730 } |
815 | 731 |
816 | 732 |
(...skipping 2922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3739 // Then check whether this scope intercepts. | 3655 // Then check whether this scope intercepts. |
3740 if ((flag & intercept_mask_)) { | 3656 if ((flag & intercept_mask_)) { |
3741 intercepted_flags_ |= flag; | 3657 intercepted_flags_ |= flag; |
3742 return true; | 3658 return true; |
3743 } | 3659 } |
3744 return false; | 3660 return false; |
3745 } | 3661 } |
3746 | 3662 |
3747 } // namespace internal | 3663 } // namespace internal |
3748 } // namespace v8 | 3664 } // namespace v8 |
OLD | NEW |