| 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); |
| 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 Handle<String> name = summ.FunctionName(); |
| 697 Handle<Object> is_eval = factory()->ToBoolean( | 655 frame->set_function_name(*name); |
| 698 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); | |
| 699 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); | |
| 700 } | 656 } |
| 701 | 657 if (options_ & StackTrace::kIsConstructor) { |
| 702 if (!function_key_.is_null()) { | 658 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 } | 659 } |
| 706 | 660 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 } | 661 } |
| 715 | 662 |
| 716 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { | 663 Handle<StackFrameInfo> NewStackFrameObject( |
| 717 Handle<JSObject> stack_frame = | 664 const FrameSummary::WasmFrameSummary& summ) { |
| 718 factory()->NewJSObject(isolate_->object_function()); | 665 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 | 666 |
| 725 // We don't have a script and hence cannot set line and col positions. | 667 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( | 668 Handle<WasmCompiledModule> compiled_module( |
| 738 summ.wasm_instance()->compiled_module(), isolate_); | 669 summ.wasm_instance()->compiled_module(), isolate_); |
| 739 Handle<String> name = WasmCompiledModule::GetFunctionName( | 670 Handle<String> name = WasmCompiledModule::GetFunctionName( |
| 740 isolate_, compiled_module, summ.function_index()); | 671 isolate_, compiled_module, summ.function_index()); |
| 741 JSObject::AddProperty(stack_frame, function_key_, name, NONE); | 672 info->set_function_name(*name); |
| 742 } | 673 } |
| 743 // Encode the function index as line number (1-based). | 674 // Encode the function index as line number (1-based). |
| 744 if (!line_key_.is_null()) { | 675 if (options_ & StackTrace::kLineNumber) { |
| 745 JSObject::AddProperty( | 676 info->set_line_number(summ.function_index() + 1); |
| 746 stack_frame, line_key_, | |
| 747 isolate_->factory()->NewNumberFromInt(summ.function_index() + 1), | |
| 748 NONE); | |
| 749 } | 677 } |
| 750 // Encode the byte offset as column (1-based). | 678 // Encode the byte offset as column (1-based). |
| 751 if (!column_key_.is_null()) { | 679 if (options_ & StackTrace::kColumnOffset) { |
| 752 int position = summ.byte_offset(); | 680 int position = summ.byte_offset(); |
| 753 // Make position 1-based. | 681 // Make position 1-based. |
| 754 if (position >= 0) ++position; | 682 if (position >= 0) ++position; |
| 755 JSObject::AddProperty(stack_frame, column_key_, | 683 info->set_column_number(position); |
| 756 isolate_->factory()->NewNumberFromInt(position), | |
| 757 NONE); | |
| 758 } | 684 } |
| 759 if (!script_id_key_.is_null()) { | 685 if (options_ & StackTrace::kScriptId) { |
| 760 int script_id = summ.script()->id(); | 686 info->set_script_id(summ.script()->id()); |
| 761 JSObject::AddProperty(stack_frame, script_id_key_, | |
| 762 handle(Smi::FromInt(script_id), isolate_), NONE); | |
| 763 } | 687 } |
| 764 | 688 return info; |
| 765 return stack_frame; | |
| 766 } | 689 } |
| 767 | 690 |
| 768 private: | 691 private: |
| 769 inline Factory* factory() { return isolate_->factory(); } | 692 inline Factory* factory() { return isolate_->factory(); } |
| 770 | 693 |
| 771 Isolate* isolate_; | 694 Isolate* isolate_; |
| 772 Handle<String> column_key_; | 695 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 }; | 696 }; |
| 781 | 697 |
| 782 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 698 Handle<JSArray> Isolate::CaptureCurrentStackTrace( |
| 783 int frame_limit, StackTrace::StackTraceOptions options) { | 699 int frame_limit, StackTrace::StackTraceOptions options) { |
| 784 DisallowJavascriptExecution no_js(this); | 700 DisallowJavascriptExecution no_js(this); |
| 785 CaptureStackTraceHelper helper(this, options); | 701 CaptureStackTraceHelper helper(this, options); |
| 786 | 702 |
| 787 // Ensure no negative values. | 703 // Ensure no negative values. |
| 788 int limit = Max(frame_limit, 0); | 704 int limit = Max(frame_limit, 0); |
| 789 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 705 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
| 790 Handle<FixedArray> stack_trace_elems( | 706 Handle<FixedArray> stack_trace_elems( |
| 791 FixedArray::cast(stack_trace->elements()), this); | 707 FixedArray::cast(stack_trace->elements()), this); |
| 792 | 708 |
| 793 int frames_seen = 0; | 709 int frames_seen = 0; |
| 794 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 710 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
| 795 it.Advance()) { | 711 it.Advance()) { |
| 796 StandardFrame* frame = it.frame(); | 712 StandardFrame* frame = it.frame(); |
| 797 // Set initial size to the maximum inlining level + 1 for the outermost | 713 // Set initial size to the maximum inlining level + 1 for the outermost |
| 798 // function. | 714 // function. |
| 799 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 715 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 800 frame->Summarize(&frames); | 716 frame->Summarize(&frames); |
| 801 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 717 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
| 802 // Filter frames from other security contexts. | 718 // Filter frames from other security contexts. |
| 803 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 719 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
| 804 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) | 720 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
| 805 continue; | 721 continue; |
| 806 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); | 722 Handle<StackFrameInfo> new_frame_obj = |
| 723 helper.NewStackFrameObject(frames[i]); |
| 807 stack_trace_elems->set(frames_seen, *new_frame_obj); | 724 stack_trace_elems->set(frames_seen, *new_frame_obj); |
| 808 frames_seen++; | 725 frames_seen++; |
| 809 } | 726 } |
| 810 } | 727 } |
| 811 | 728 |
| 812 stack_trace->set_length(Smi::FromInt(frames_seen)); | 729 stack_trace->set_length(Smi::FromInt(frames_seen)); |
| 813 return stack_trace; | 730 return stack_trace; |
| 814 } | 731 } |
| 815 | 732 |
| 816 | 733 |
| (...skipping 2922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3739 // Then check whether this scope intercepts. | 3656 // Then check whether this scope intercepts. |
| 3740 if ((flag & intercept_mask_)) { | 3657 if ((flag & intercept_mask_)) { |
| 3741 intercepted_flags_ |= flag; | 3658 intercepted_flags_ |= flag; |
| 3742 return true; | 3659 return true; |
| 3743 } | 3660 } |
| 3744 return false; | 3661 return false; |
| 3745 } | 3662 } |
| 3746 | 3663 |
| 3747 } // namespace internal | 3664 } // namespace internal |
| 3748 } // namespace v8 | 3665 } // namespace v8 |
| OLD | NEW |