| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 info->set_is_wasm(true); | 740 info->set_is_wasm(true); |
| 741 return info; | 741 return info; |
| 742 } | 742 } |
| 743 | 743 |
| 744 private: | 744 private: |
| 745 inline Factory* factory() { return isolate_->factory(); } | 745 inline Factory* factory() { return isolate_->factory(); } |
| 746 | 746 |
| 747 Isolate* isolate_; | 747 Isolate* isolate_; |
| 748 }; | 748 }; |
| 749 | 749 |
| 750 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 750 Handle<FixedArray> Isolate::CaptureCurrentStackTrace( |
| 751 int frame_limit, StackTrace::StackTraceOptions options) { | 751 int frame_limit, StackTrace::StackTraceOptions options) { |
| 752 DisallowJavascriptExecution no_js(this); | 752 DisallowJavascriptExecution no_js(this); |
| 753 CaptureStackTraceHelper helper(this); | 753 CaptureStackTraceHelper helper(this); |
| 754 | 754 |
| 755 // Ensure no negative values. | 755 // Ensure no negative values. |
| 756 int limit = Max(frame_limit, 0); | 756 int limit = Max(frame_limit, 0); |
| 757 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 757 Handle<FixedArray> stack_trace_elems = factory()->NewFixedArray(limit); |
| 758 Handle<FixedArray> stack_trace_elems( | |
| 759 FixedArray::cast(stack_trace->elements()), this); | |
| 760 | 758 |
| 761 int frames_seen = 0; | 759 int frames_seen = 0; |
| 762 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 760 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
| 763 it.Advance()) { | 761 it.Advance()) { |
| 764 StandardFrame* frame = it.frame(); | 762 StandardFrame* frame = it.frame(); |
| 765 // Set initial size to the maximum inlining level + 1 for the outermost | 763 // Set initial size to the maximum inlining level + 1 for the outermost |
| 766 // function. | 764 // function. |
| 767 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 765 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 768 frame->Summarize(&frames); | 766 frame->Summarize(&frames); |
| 769 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 767 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
| 770 // Filter frames from other security contexts. | 768 // Filter frames from other security contexts. |
| 771 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 769 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
| 772 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) | 770 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
| 773 continue; | 771 continue; |
| 774 Handle<StackFrameInfo> new_frame_obj = | 772 Handle<StackFrameInfo> new_frame_obj = |
| 775 helper.NewStackFrameObject(frames[i]); | 773 helper.NewStackFrameObject(frames[i]); |
| 776 stack_trace_elems->set(frames_seen, *new_frame_obj); | 774 stack_trace_elems->set(frames_seen, *new_frame_obj); |
| 777 frames_seen++; | 775 frames_seen++; |
| 778 } | 776 } |
| 779 } | 777 } |
| 780 | 778 stack_trace_elems->Shrink(frames_seen); |
| 781 stack_trace->set_length(Smi::FromInt(frames_seen)); | 779 return stack_trace_elems; |
| 782 return stack_trace; | |
| 783 } | 780 } |
| 784 | 781 |
| 785 | 782 |
| 786 void Isolate::PrintStack(FILE* out, PrintStackMode mode) { | 783 void Isolate::PrintStack(FILE* out, PrintStackMode mode) { |
| 787 if (stack_trace_nesting_level_ == 0) { | 784 if (stack_trace_nesting_level_ == 0) { |
| 788 stack_trace_nesting_level_++; | 785 stack_trace_nesting_level_++; |
| 789 StringStream::ClearMentionedObjectCache(this); | 786 StringStream::ClearMentionedObjectCache(this); |
| 790 HeapStringAllocator allocator; | 787 HeapStringAllocator allocator; |
| 791 StringStream accumulator(&allocator); | 788 StringStream accumulator(&allocator); |
| 792 incomplete_message_ = &accumulator; | 789 incomplete_message_ = &accumulator; |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 *target = MessageLocation(casted_script, pos, pos + 1); | 1660 *target = MessageLocation(casted_script, pos, pos + 1); |
| 1664 return true; | 1661 return true; |
| 1665 } | 1662 } |
| 1666 } | 1663 } |
| 1667 return false; | 1664 return false; |
| 1668 } | 1665 } |
| 1669 | 1666 |
| 1670 | 1667 |
| 1671 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, | 1668 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, |
| 1672 MessageLocation* location) { | 1669 MessageLocation* location) { |
| 1673 Handle<JSArray> stack_trace_object; | 1670 Handle<FixedArray> stack_trace_object; |
| 1674 if (capture_stack_trace_for_uncaught_exceptions_) { | 1671 if (capture_stack_trace_for_uncaught_exceptions_) { |
| 1675 if (exception->IsJSError()) { | 1672 if (exception->IsJSError()) { |
| 1676 // We fetch the stack trace that corresponds to this error object. | 1673 // We fetch the stack trace that corresponds to this error object. |
| 1677 // If the lookup fails, the exception is probably not a valid Error | 1674 // If the lookup fails, the exception is probably not a valid Error |
| 1678 // object. In that case, we fall through and capture the stack trace | 1675 // object. In that case, we fall through and capture the stack trace |
| 1679 // at this throw site. | 1676 // at this throw site. |
| 1680 stack_trace_object = | 1677 stack_trace_object = |
| 1681 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); | 1678 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); |
| 1682 } | 1679 } |
| 1683 if (stack_trace_object.is_null()) { | 1680 if (stack_trace_object.is_null()) { |
| (...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3390 | 3387 |
| 3391 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { | 3388 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { |
| 3392 promise_reject_callback_ = callback; | 3389 promise_reject_callback_ = callback; |
| 3393 } | 3390 } |
| 3394 | 3391 |
| 3395 | 3392 |
| 3396 void Isolate::ReportPromiseReject(Handle<JSObject> promise, | 3393 void Isolate::ReportPromiseReject(Handle<JSObject> promise, |
| 3397 Handle<Object> value, | 3394 Handle<Object> value, |
| 3398 v8::PromiseRejectEvent event) { | 3395 v8::PromiseRejectEvent event) { |
| 3399 if (promise_reject_callback_ == NULL) return; | 3396 if (promise_reject_callback_ == NULL) return; |
| 3400 Handle<JSArray> stack_trace; | 3397 Handle<FixedArray> stack_trace; |
| 3401 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { | 3398 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { |
| 3402 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); | 3399 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); |
| 3403 } | 3400 } |
| 3404 promise_reject_callback_(v8::PromiseRejectMessage( | 3401 promise_reject_callback_(v8::PromiseRejectMessage( |
| 3405 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), | 3402 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), |
| 3406 v8::Utils::StackTraceToLocal(stack_trace))); | 3403 v8::Utils::StackTraceToLocal(stack_trace))); |
| 3407 } | 3404 } |
| 3408 | 3405 |
| 3409 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, | 3406 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, |
| 3410 MaybeHandle<Object>* result, | 3407 MaybeHandle<Object>* result, |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3773 // Then check whether this scope intercepts. | 3770 // Then check whether this scope intercepts. |
| 3774 if ((flag & intercept_mask_)) { | 3771 if ((flag & intercept_mask_)) { |
| 3775 intercepted_flags_ |= flag; | 3772 intercepted_flags_ |= flag; |
| 3776 return true; | 3773 return true; |
| 3777 } | 3774 } |
| 3778 return false; | 3775 return false; |
| 3779 } | 3776 } |
| 3780 | 3777 |
| 3781 } // namespace internal | 3778 } // namespace internal |
| 3782 } // namespace v8 | 3779 } // namespace v8 |
| OLD | NEW |