OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 599 matching lines...) Loading... |
610 Handle<Object> caller, | 610 Handle<Object> caller, |
611 int limit) { | 611 int limit) { |
612 limit = Max(limit, 0); // Ensure that limit is not negative. | 612 limit = Max(limit, 0); // Ensure that limit is not negative. |
613 int initial_size = Min(limit, 10); | 613 int initial_size = Min(limit, 10); |
614 Handle<FixedArray> elements = | 614 Handle<FixedArray> elements = |
615 factory()->NewFixedArrayWithHoles(initial_size * 4); | 615 factory()->NewFixedArrayWithHoles(initial_size * 4); |
616 | 616 |
617 // If the caller parameter is a function we skip frames until we're | 617 // If the caller parameter is a function we skip frames until we're |
618 // under it before starting to collect. | 618 // under it before starting to collect. |
619 bool seen_caller = !caller->IsJSFunction(); | 619 bool seen_caller = !caller->IsJSFunction(); |
620 int cursor = 0; | 620 // First element is reserved to store the number of non-strict frames. |
| 621 int cursor = 1; |
621 int frames_seen = 0; | 622 int frames_seen = 0; |
| 623 int non_strict_frames = 0; |
| 624 bool encountered_strict_function = false; |
622 for (StackFrameIterator iter(this); | 625 for (StackFrameIterator iter(this); |
623 !iter.done() && frames_seen < limit; | 626 !iter.done() && frames_seen < limit; |
624 iter.Advance()) { | 627 iter.Advance()) { |
625 StackFrame* raw_frame = iter.frame(); | 628 StackFrame* raw_frame = iter.frame(); |
626 if (IsVisibleInStackTrace(raw_frame, *caller, &seen_caller)) { | 629 if (IsVisibleInStackTrace(raw_frame, *caller, &seen_caller)) { |
627 frames_seen++; | 630 frames_seen++; |
628 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 631 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
629 // Set initial size to the maximum inlining level + 1 for the outermost | 632 // Set initial size to the maximum inlining level + 1 for the outermost |
630 // function. | 633 // function. |
631 List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1); | 634 List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1); |
632 frame->Summarize(&frames); | 635 frame->Summarize(&frames); |
633 for (int i = frames.length() - 1; i >= 0; i--) { | 636 for (int i = frames.length() - 1; i >= 0; i--) { |
634 if (cursor + 4 > elements->length()) { | 637 if (cursor + 4 > elements->length()) { |
635 int new_capacity = JSObject::NewElementsCapacity(elements->length()); | 638 int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
636 Handle<FixedArray> new_elements = | 639 Handle<FixedArray> new_elements = |
637 factory()->NewFixedArrayWithHoles(new_capacity); | 640 factory()->NewFixedArrayWithHoles(new_capacity); |
638 for (int i = 0; i < cursor; i++) { | 641 for (int i = 0; i < cursor; i++) { |
639 new_elements->set(i, elements->get(i)); | 642 new_elements->set(i, elements->get(i)); |
640 } | 643 } |
641 elements = new_elements; | 644 elements = new_elements; |
642 } | 645 } |
643 ASSERT(cursor + 4 <= elements->length()); | 646 ASSERT(cursor + 4 <= elements->length()); |
644 | 647 |
645 Handle<Object> recv = frames[i].receiver(); | 648 Handle<Object> recv = frames[i].receiver(); |
646 Handle<JSFunction> fun = frames[i].function(); | 649 Handle<JSFunction> fun = frames[i].function(); |
647 Handle<Code> code = frames[i].code(); | 650 Handle<Code> code = frames[i].code(); |
648 Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this); | 651 Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this); |
| 652 // The stack trace API should not expose receivers and function |
| 653 // objects on frames deeper than the top-most one with a strict |
| 654 // mode function. The number of non-strict frames is stored as |
| 655 // first element in the result array. |
| 656 if (!encountered_strict_function) { |
| 657 if (!fun->shared()->is_classic_mode()) { |
| 658 encountered_strict_function = true; |
| 659 } else { |
| 660 non_strict_frames++; |
| 661 } |
| 662 } |
649 elements->set(cursor++, *recv); | 663 elements->set(cursor++, *recv); |
650 elements->set(cursor++, *fun); | 664 elements->set(cursor++, *fun); |
651 elements->set(cursor++, *code); | 665 elements->set(cursor++, *code); |
652 elements->set(cursor++, *offset); | 666 elements->set(cursor++, *offset); |
653 } | 667 } |
654 } | 668 } |
655 } | 669 } |
| 670 elements->set(0, Smi::FromInt(non_strict_frames)); |
656 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements); | 671 Handle<JSArray> result = factory()->NewJSArrayWithElements(elements); |
657 result->set_length(Smi::FromInt(cursor)); | 672 result->set_length(Smi::FromInt(cursor)); |
658 return result; | 673 return result; |
659 } | 674 } |
660 | 675 |
661 | 676 |
662 void Isolate::CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object) { | 677 void Isolate::CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object) { |
663 if (capture_stack_trace_for_uncaught_exceptions_) { | 678 if (capture_stack_trace_for_uncaught_exceptions_) { |
664 // Capture stack trace for a detailed exception message. | 679 // Capture stack trace for a detailed exception message. |
665 Handle<String> key = factory()->hidden_stack_trace_string(); | 680 Handle<String> key = factory()->hidden_stack_trace_string(); |
(...skipping 1699 matching lines...) Loading... |
2365 | 2380 |
2366 #ifdef DEBUG | 2381 #ifdef DEBUG |
2367 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 2382 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
2368 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 2383 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
2369 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 2384 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
2370 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 2385 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
2371 #undef ISOLATE_FIELD_OFFSET | 2386 #undef ISOLATE_FIELD_OFFSET |
2372 #endif | 2387 #endif |
2373 | 2388 |
2374 } } // namespace v8::internal | 2389 } } // namespace v8::internal |
OLD | NEW |