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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 | 613 |
614 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. | 614 // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. |
615 return factory()->NewJSArrayWithElements(elements); | 615 return factory()->NewJSArrayWithElements(elements); |
616 } | 616 } |
617 | 617 |
618 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( | 618 MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( |
619 Handle<JSReceiver> error_object) { | 619 Handle<JSReceiver> error_object) { |
620 if (capture_stack_trace_for_uncaught_exceptions_) { | 620 if (capture_stack_trace_for_uncaught_exceptions_) { |
621 // Capture stack trace for a detailed exception message. | 621 // Capture stack trace for a detailed exception message. |
622 Handle<Name> key = factory()->detailed_stack_trace_symbol(); | 622 Handle<Name> key = factory()->detailed_stack_trace_symbol(); |
623 Handle<JSArray> stack_trace = CaptureCurrentStackTrace( | 623 Handle<FixedArray> stack_trace = CaptureCurrentStackTrace( |
624 stack_trace_for_uncaught_exceptions_frame_limit_, | 624 stack_trace_for_uncaught_exceptions_frame_limit_, |
625 stack_trace_for_uncaught_exceptions_options_); | 625 stack_trace_for_uncaught_exceptions_options_); |
626 RETURN_ON_EXCEPTION( | 626 RETURN_ON_EXCEPTION( |
627 this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), | 627 this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), |
628 JSReceiver); | 628 JSReceiver); |
629 } | 629 } |
630 return error_object; | 630 return error_object; |
631 } | 631 } |
632 | 632 |
633 MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace( | 633 MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace( |
634 Handle<JSReceiver> error_object, FrameSkipMode mode, | 634 Handle<JSReceiver> error_object, FrameSkipMode mode, |
635 Handle<Object> caller) { | 635 Handle<Object> caller) { |
636 // Capture stack trace for simple stack trace string formatting. | 636 // Capture stack trace for simple stack trace string formatting. |
637 Handle<Name> key = factory()->stack_trace_symbol(); | 637 Handle<Name> key = factory()->stack_trace_symbol(); |
638 Handle<Object> stack_trace = | 638 Handle<Object> stack_trace = |
639 CaptureSimpleStackTrace(error_object, mode, caller); | 639 CaptureSimpleStackTrace(error_object, mode, caller); |
640 RETURN_ON_EXCEPTION( | 640 RETURN_ON_EXCEPTION( |
641 this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), | 641 this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), |
642 JSReceiver); | 642 JSReceiver); |
643 return error_object; | 643 return error_object; |
644 } | 644 } |
645 | 645 |
646 | 646 Handle<FixedArray> Isolate::GetDetailedStackTrace( |
647 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) { | 647 Handle<JSObject> error_object) { |
648 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol(); | 648 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol(); |
649 Handle<Object> stack_trace = | 649 Handle<Object> stack_trace = |
650 JSReceiver::GetDataProperty(error_object, key_detailed); | 650 JSReceiver::GetDataProperty(error_object, key_detailed); |
651 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); | 651 if (stack_trace->IsFixedArray()) return Handle<FixedArray>::cast(stack_trace); |
652 return Handle<JSArray>(); | 652 return Handle<FixedArray>(); |
653 } | 653 } |
654 | 654 |
655 | 655 |
656 class CaptureStackTraceHelper { | 656 class CaptureStackTraceHelper { |
657 public: | 657 public: |
658 explicit CaptureStackTraceHelper(Isolate* isolate) : isolate_(isolate) {} | 658 explicit CaptureStackTraceHelper(Isolate* isolate) : isolate_(isolate) {} |
659 | 659 |
660 Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) { | 660 Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) { |
661 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); | 661 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); |
662 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); | 662 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 info->set_is_wasm(true); | 707 info->set_is_wasm(true); |
708 return info; | 708 return info; |
709 } | 709 } |
710 | 710 |
711 private: | 711 private: |
712 inline Factory* factory() { return isolate_->factory(); } | 712 inline Factory* factory() { return isolate_->factory(); } |
713 | 713 |
714 Isolate* isolate_; | 714 Isolate* isolate_; |
715 }; | 715 }; |
716 | 716 |
717 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 717 Handle<FixedArray> Isolate::CaptureCurrentStackTrace( |
718 int frame_limit, StackTrace::StackTraceOptions options) { | 718 int frame_limit, StackTrace::StackTraceOptions options) { |
719 DisallowJavascriptExecution no_js(this); | 719 DisallowJavascriptExecution no_js(this); |
720 CaptureStackTraceHelper helper(this); | 720 CaptureStackTraceHelper helper(this); |
721 | 721 |
722 // Ensure no negative values. | 722 // Ensure no negative values. |
723 int limit = Max(frame_limit, 0); | 723 int limit = Max(frame_limit, 0); |
724 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 724 Handle<FixedArray> stack_trace_elems = factory()->NewFixedArray(limit); |
725 Handle<FixedArray> stack_trace_elems( | |
726 FixedArray::cast(stack_trace->elements()), this); | |
727 | 725 |
728 int frames_seen = 0; | 726 int frames_seen = 0; |
729 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 727 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
730 it.Advance()) { | 728 it.Advance()) { |
731 StandardFrame* frame = it.frame(); | 729 StandardFrame* frame = it.frame(); |
732 // Set initial size to the maximum inlining level + 1 for the outermost | 730 // Set initial size to the maximum inlining level + 1 for the outermost |
733 // function. | 731 // function. |
734 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 732 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
735 frame->Summarize(&frames); | 733 frame->Summarize(&frames); |
736 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 734 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
737 // Filter frames from other security contexts. | 735 // Filter frames from other security contexts. |
738 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 736 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
739 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) | 737 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
740 continue; | 738 continue; |
741 Handle<StackFrameInfo> new_frame_obj = | 739 Handle<StackFrameInfo> new_frame_obj = |
742 helper.NewStackFrameObject(frames[i]); | 740 helper.NewStackFrameObject(frames[i]); |
743 stack_trace_elems->set(frames_seen, *new_frame_obj); | 741 stack_trace_elems->set(frames_seen, *new_frame_obj); |
744 frames_seen++; | 742 frames_seen++; |
745 } | 743 } |
746 } | 744 } |
747 | 745 stack_trace_elems->Shrink(frames_seen); |
748 stack_trace->set_length(Smi::FromInt(frames_seen)); | 746 return stack_trace_elems; |
749 return stack_trace; | |
750 } | 747 } |
751 | 748 |
752 | 749 |
753 void Isolate::PrintStack(FILE* out, PrintStackMode mode) { | 750 void Isolate::PrintStack(FILE* out, PrintStackMode mode) { |
754 if (stack_trace_nesting_level_ == 0) { | 751 if (stack_trace_nesting_level_ == 0) { |
755 stack_trace_nesting_level_++; | 752 stack_trace_nesting_level_++; |
756 StringStream::ClearMentionedObjectCache(this); | 753 StringStream::ClearMentionedObjectCache(this); |
757 HeapStringAllocator allocator; | 754 HeapStringAllocator allocator; |
758 StringStream accumulator(&allocator); | 755 StringStream accumulator(&allocator); |
759 incomplete_message_ = &accumulator; | 756 incomplete_message_ = &accumulator; |
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 *target = MessageLocation(casted_script, pos, pos + 1); | 1627 *target = MessageLocation(casted_script, pos, pos + 1); |
1631 return true; | 1628 return true; |
1632 } | 1629 } |
1633 } | 1630 } |
1634 return false; | 1631 return false; |
1635 } | 1632 } |
1636 | 1633 |
1637 | 1634 |
1638 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, | 1635 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, |
1639 MessageLocation* location) { | 1636 MessageLocation* location) { |
1640 Handle<JSArray> stack_trace_object; | 1637 Handle<FixedArray> stack_trace_object; |
1641 if (capture_stack_trace_for_uncaught_exceptions_) { | 1638 if (capture_stack_trace_for_uncaught_exceptions_) { |
1642 if (exception->IsJSError()) { | 1639 if (exception->IsJSError()) { |
1643 // We fetch the stack trace that corresponds to this error object. | 1640 // We fetch the stack trace that corresponds to this error object. |
1644 // If the lookup fails, the exception is probably not a valid Error | 1641 // If the lookup fails, the exception is probably not a valid Error |
1645 // object. In that case, we fall through and capture the stack trace | 1642 // object. In that case, we fall through and capture the stack trace |
1646 // at this throw site. | 1643 // at this throw site. |
1647 stack_trace_object = | 1644 stack_trace_object = |
1648 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); | 1645 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); |
1649 } | 1646 } |
1650 if (stack_trace_object.is_null()) { | 1647 if (stack_trace_object.is_null()) { |
(...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3357 | 3354 |
3358 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { | 3355 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { |
3359 promise_reject_callback_ = callback; | 3356 promise_reject_callback_ = callback; |
3360 } | 3357 } |
3361 | 3358 |
3362 | 3359 |
3363 void Isolate::ReportPromiseReject(Handle<JSObject> promise, | 3360 void Isolate::ReportPromiseReject(Handle<JSObject> promise, |
3364 Handle<Object> value, | 3361 Handle<Object> value, |
3365 v8::PromiseRejectEvent event) { | 3362 v8::PromiseRejectEvent event) { |
3366 if (promise_reject_callback_ == NULL) return; | 3363 if (promise_reject_callback_ == NULL) return; |
3367 Handle<JSArray> stack_trace; | 3364 Handle<FixedArray> stack_trace; |
3368 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { | 3365 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { |
3369 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); | 3366 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); |
3370 } | 3367 } |
3371 promise_reject_callback_(v8::PromiseRejectMessage( | 3368 promise_reject_callback_(v8::PromiseRejectMessage( |
3372 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), | 3369 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), |
3373 v8::Utils::StackTraceToLocal(stack_trace))); | 3370 v8::Utils::StackTraceToLocal(stack_trace))); |
3374 } | 3371 } |
3375 | 3372 |
3376 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, | 3373 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, |
3377 MaybeHandle<Object>* result, | 3374 MaybeHandle<Object>* result, |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3740 // Then check whether this scope intercepts. | 3737 // Then check whether this scope intercepts. |
3741 if ((flag & intercept_mask_)) { | 3738 if ((flag & intercept_mask_)) { |
3742 intercepted_flags_ |= flag; | 3739 intercepted_flags_ |= flag; |
3743 return true; | 3740 return true; |
3744 } | 3741 } |
3745 return false; | 3742 return false; |
3746 } | 3743 } |
3747 | 3744 |
3748 } // namespace internal | 3745 } // namespace internal |
3749 } // namespace v8 | 3746 } // namespace v8 |
OLD | NEW |