| 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 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 JSReceiver); | 538 JSReceiver); |
| 539 return error_object; | 539 return error_object; |
| 540 } | 540 } |
| 541 | 541 |
| 542 | 542 |
| 543 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) { | 543 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) { |
| 544 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol(); | 544 Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol(); |
| 545 Handle<Object> stack_trace = | 545 Handle<Object> stack_trace = |
| 546 JSReceiver::GetDataProperty(error_object, key_detailed); | 546 JSReceiver::GetDataProperty(error_object, key_detailed); |
| 547 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); | 547 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); |
| 548 | 548 return Handle<JSArray>(); |
| 549 if (!capture_stack_trace_for_uncaught_exceptions_) return Handle<JSArray>(); | |
| 550 | |
| 551 // Try to get details from simple stack trace. | |
| 552 Handle<JSArray> detailed_stack_trace = | |
| 553 GetDetailedFromSimpleStackTrace(error_object); | |
| 554 if (!detailed_stack_trace.is_null()) { | |
| 555 // Save the detailed stack since the simple one might be withdrawn later. | |
| 556 JSObject::SetProperty(error_object, key_detailed, detailed_stack_trace, | |
| 557 STRICT).Assert(); | |
| 558 } | |
| 559 return detailed_stack_trace; | |
| 560 } | 549 } |
| 561 | 550 |
| 562 | 551 |
| 563 class CaptureStackTraceHelper { | 552 class CaptureStackTraceHelper { |
| 564 public: | 553 public: |
| 565 CaptureStackTraceHelper(Isolate* isolate, | 554 CaptureStackTraceHelper(Isolate* isolate, |
| 566 StackTrace::StackTraceOptions options) | 555 StackTrace::StackTraceOptions options) |
| 567 : isolate_(isolate) { | 556 : isolate_(isolate) { |
| 568 if (options & StackTrace::kColumnOffset) { | 557 if (options & StackTrace::kColumnOffset) { |
| 569 column_key_ = | 558 column_key_ = |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 Object* maybe_code = elements->get(index + 2); | 721 Object* maybe_code = elements->get(index + 2); |
| 733 if (maybe_code->IsSmi()) { | 722 if (maybe_code->IsSmi()) { |
| 734 return Smi::cast(maybe_code)->value(); | 723 return Smi::cast(maybe_code)->value(); |
| 735 } else { | 724 } else { |
| 736 AbstractCode* abstract_code = AbstractCode::cast(maybe_code); | 725 AbstractCode* abstract_code = AbstractCode::cast(maybe_code); |
| 737 int code_offset = Smi::cast(elements->get(index + 3))->value(); | 726 int code_offset = Smi::cast(elements->get(index + 3))->value(); |
| 738 return abstract_code->SourcePosition(code_offset); | 727 return abstract_code->SourcePosition(code_offset); |
| 739 } | 728 } |
| 740 } | 729 } |
| 741 | 730 |
| 742 | |
| 743 Handle<JSArray> Isolate::GetDetailedFromSimpleStackTrace( | |
| 744 Handle<JSObject> error_object) { | |
| 745 Handle<Name> key = factory()->stack_trace_symbol(); | |
| 746 Handle<Object> property = JSReceiver::GetDataProperty(error_object, key); | |
| 747 if (!property->IsJSArray()) return Handle<JSArray>(); | |
| 748 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); | |
| 749 | |
| 750 CaptureStackTraceHelper helper(this, | |
| 751 stack_trace_for_uncaught_exceptions_options_); | |
| 752 | |
| 753 int frames_seen = 0; | |
| 754 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); | |
| 755 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); | |
| 756 | |
| 757 int frame_limit = stack_trace_for_uncaught_exceptions_frame_limit_; | |
| 758 if (frame_limit < 0) frame_limit = (elements_limit - 1) / 4; | |
| 759 | |
| 760 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | |
| 761 for (int i = 1; i < elements_limit && frames_seen < frame_limit; i += 4) { | |
| 762 Handle<Object> recv = handle(elements->get(i), this); | |
| 763 Handle<JSFunction> fun = | |
| 764 handle(JSFunction::cast(elements->get(i + 1)), this); | |
| 765 bool is_constructor = | |
| 766 recv->IsJSObject() && | |
| 767 Handle<JSObject>::cast(recv)->map()->GetConstructor() == *fun; | |
| 768 int position = PositionFromStackTrace(elements, i); | |
| 769 | |
| 770 Handle<JSObject> stack_frame = | |
| 771 helper.NewStackFrameObject(fun, position, is_constructor); | |
| 772 | |
| 773 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame); | |
| 774 frames_seen++; | |
| 775 } | |
| 776 | |
| 777 stack_trace->set_length(Smi::FromInt(frames_seen)); | |
| 778 return stack_trace; | |
| 779 } | |
| 780 | |
| 781 | |
| 782 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 731 Handle<JSArray> Isolate::CaptureCurrentStackTrace( |
| 783 int frame_limit, StackTrace::StackTraceOptions options) { | 732 int frame_limit, StackTrace::StackTraceOptions options) { |
| 784 CaptureStackTraceHelper helper(this, options); | 733 CaptureStackTraceHelper helper(this, options); |
| 785 | 734 |
| 786 // Ensure no negative values. | 735 // Ensure no negative values. |
| 787 int limit = Max(frame_limit, 0); | 736 int limit = Max(frame_limit, 0); |
| 788 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 737 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
| 789 Handle<FixedArray> stack_trace_elems( | 738 Handle<FixedArray> stack_trace_elems( |
| 790 FixedArray::cast(stack_trace->elements()), this); | 739 FixedArray::cast(stack_trace->elements()), this); |
| 791 | 740 |
| (...skipping 2331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3123 // Then check whether this scope intercepts. | 3072 // Then check whether this scope intercepts. |
| 3124 if ((flag & intercept_mask_)) { | 3073 if ((flag & intercept_mask_)) { |
| 3125 intercepted_flags_ |= flag; | 3074 intercepted_flags_ |= flag; |
| 3126 return true; | 3075 return true; |
| 3127 } | 3076 } |
| 3128 return false; | 3077 return false; |
| 3129 } | 3078 } |
| 3130 | 3079 |
| 3131 } // namespace internal | 3080 } // namespace internal |
| 3132 } // namespace v8 | 3081 } // namespace v8 |
| OLD | NEW |