| 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 |