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 <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 if (options & StackTrace::kIsEval) { | 495 if (options & StackTrace::kIsEval) { |
496 eval_key_ = | 496 eval_key_ = |
497 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); | 497 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); |
498 } | 498 } |
499 if (options & StackTrace::kIsConstructor) { | 499 if (options & StackTrace::kIsConstructor) { |
500 constructor_key_ = factory()->InternalizeOneByteString( | 500 constructor_key_ = factory()->InternalizeOneByteString( |
501 STATIC_CHAR_VECTOR("isConstructor")); | 501 STATIC_CHAR_VECTOR("isConstructor")); |
502 } | 502 } |
503 } | 503 } |
504 | 504 |
505 Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, | 505 Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, int position, |
506 Handle<Code> code, Address pc, | |
507 bool is_constructor) { | 506 bool is_constructor) { |
508 Handle<JSObject> stack_frame = | 507 Handle<JSObject> stack_frame = |
509 factory()->NewJSObject(isolate_->object_function()); | 508 factory()->NewJSObject(isolate_->object_function()); |
510 | 509 |
511 Handle<Script> script(Script::cast(fun->shared()->script())); | 510 Handle<Script> script(Script::cast(fun->shared()->script())); |
512 | 511 |
513 if (!line_key_.is_null()) { | 512 if (!line_key_.is_null()) { |
514 int script_line_offset = script->line_offset()->value(); | 513 int script_line_offset = script->line_offset()->value(); |
515 int position = code->SourcePosition(pc); | |
516 int line_number = Script::GetLineNumber(script, position); | 514 int line_number = Script::GetLineNumber(script, position); |
517 // line_number is already shifted by the script_line_offset. | 515 // line_number is already shifted by the script_line_offset. |
518 int relative_line_number = line_number - script_line_offset; | 516 int relative_line_number = line_number - script_line_offset; |
519 if (!column_key_.is_null() && relative_line_number >= 0) { | 517 if (!column_key_.is_null() && relative_line_number >= 0) { |
520 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); | 518 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); |
521 int start = (relative_line_number == 0) ? 0 : | 519 int start = (relative_line_number == 0) ? 0 : |
522 Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1; | 520 Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1; |
523 int column_offset = position - start; | 521 int column_offset = position - start; |
524 if (relative_line_number == 0) { | 522 if (relative_line_number == 0) { |
525 // For the case where the code is on the same line as the script | 523 // For the case where the code is on the same line as the script |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 Handle<String> line_key_; | 577 Handle<String> line_key_; |
580 Handle<String> script_id_key_; | 578 Handle<String> script_id_key_; |
581 Handle<String> script_name_key_; | 579 Handle<String> script_name_key_; |
582 Handle<String> script_name_or_source_url_key_; | 580 Handle<String> script_name_or_source_url_key_; |
583 Handle<String> function_key_; | 581 Handle<String> function_key_; |
584 Handle<String> eval_key_; | 582 Handle<String> eval_key_; |
585 Handle<String> constructor_key_; | 583 Handle<String> constructor_key_; |
586 }; | 584 }; |
587 | 585 |
588 | 586 |
| 587 int PositionFromStackTrace(Handle<FixedArray> elements, int index) { |
| 588 DisallowHeapAllocation no_gc; |
| 589 Object* maybe_code = elements->get(index + 2); |
| 590 if (maybe_code->IsSmi()) { |
| 591 return Smi::cast(maybe_code)->value(); |
| 592 } else { |
| 593 Code* code = Code::cast(maybe_code); |
| 594 Address pc = code->address() + Smi::cast(elements->get(index + 3))->value(); |
| 595 return code->SourcePosition(pc); |
| 596 } |
| 597 } |
| 598 |
| 599 |
589 Handle<JSArray> Isolate::GetDetailedFromSimpleStackTrace( | 600 Handle<JSArray> Isolate::GetDetailedFromSimpleStackTrace( |
590 Handle<JSObject> error_object) { | 601 Handle<JSObject> error_object) { |
591 Handle<Name> key = factory()->stack_trace_symbol(); | 602 Handle<Name> key = factory()->stack_trace_symbol(); |
592 Handle<Object> property = JSObject::GetDataProperty(error_object, key); | 603 Handle<Object> property = JSObject::GetDataProperty(error_object, key); |
593 if (!property->IsJSArray()) return Handle<JSArray>(); | 604 if (!property->IsJSArray()) return Handle<JSArray>(); |
594 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); | 605 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); |
595 | 606 |
596 CaptureStackTraceHelper helper(this, | 607 CaptureStackTraceHelper helper(this, |
597 stack_trace_for_uncaught_exceptions_options_); | 608 stack_trace_for_uncaught_exceptions_options_); |
598 | 609 |
599 int frames_seen = 0; | 610 int frames_seen = 0; |
600 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); | 611 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); |
601 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); | 612 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); |
602 | 613 |
603 int frame_limit = stack_trace_for_uncaught_exceptions_frame_limit_; | 614 int frame_limit = stack_trace_for_uncaught_exceptions_frame_limit_; |
604 if (frame_limit < 0) frame_limit = (elements_limit - 1) / 4; | 615 if (frame_limit < 0) frame_limit = (elements_limit - 1) / 4; |
605 | 616 |
606 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 617 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
607 for (int i = 1; i < elements_limit && frames_seen < frame_limit; i += 4) { | 618 for (int i = 1; i < elements_limit && frames_seen < frame_limit; i += 4) { |
608 Handle<Object> recv = handle(elements->get(i), this); | 619 Handle<Object> recv = handle(elements->get(i), this); |
609 Handle<JSFunction> fun = | 620 Handle<JSFunction> fun = |
610 handle(JSFunction::cast(elements->get(i + 1)), this); | 621 handle(JSFunction::cast(elements->get(i + 1)), this); |
611 Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this); | |
612 Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this); | |
613 Address pc = code->address() + offset->value(); | |
614 bool is_constructor = | 622 bool is_constructor = |
615 recv->IsJSObject() && | 623 recv->IsJSObject() && |
616 Handle<JSObject>::cast(recv)->map()->GetConstructor() == *fun; | 624 Handle<JSObject>::cast(recv)->map()->GetConstructor() == *fun; |
| 625 int position = PositionFromStackTrace(elements, i); |
617 | 626 |
618 Handle<JSObject> stack_frame = | 627 Handle<JSObject> stack_frame = |
619 helper.NewStackFrameObject(fun, code, pc, is_constructor); | 628 helper.NewStackFrameObject(fun, position, is_constructor); |
620 | 629 |
621 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame); | 630 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame); |
622 frames_seen++; | 631 frames_seen++; |
623 } | 632 } |
624 | 633 |
625 stack_trace->set_length(Smi::FromInt(frames_seen)); | 634 stack_trace->set_length(Smi::FromInt(frames_seen)); |
626 return stack_trace; | 635 return stack_trace; |
627 } | 636 } |
628 | 637 |
629 | 638 |
(...skipping 11 matching lines...) Expand all Loading... |
641 JavaScriptFrame* frame = it.frame(); | 650 JavaScriptFrame* frame = it.frame(); |
642 // Set initial size to the maximum inlining level + 1 for the outermost | 651 // Set initial size to the maximum inlining level + 1 for the outermost |
643 // function. | 652 // function. |
644 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 653 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
645 frame->Summarize(&frames); | 654 frame->Summarize(&frames); |
646 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 655 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
647 Handle<JSFunction> fun = frames[i].function(); | 656 Handle<JSFunction> fun = frames[i].function(); |
648 // Filter frames from other security contexts. | 657 // Filter frames from other security contexts. |
649 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 658 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
650 !this->context()->HasSameSecurityTokenAs(fun->context())) continue; | 659 !this->context()->HasSameSecurityTokenAs(fun->context())) continue; |
651 | 660 int position = frames[i].code()->SourcePosition(frames[i].pc()); |
652 Handle<JSObject> stack_frame = helper.NewStackFrameObject( | 661 Handle<JSObject> stack_frame = |
653 fun, frames[i].code(), frames[i].pc(), frames[i].is_constructor()); | 662 helper.NewStackFrameObject(fun, position, frames[i].is_constructor()); |
654 | 663 |
655 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame); | 664 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame); |
656 frames_seen++; | 665 frames_seen++; |
657 } | 666 } |
658 it.Advance(); | 667 it.Advance(); |
659 } | 668 } |
660 | 669 |
661 stack_trace->set_length(Smi::FromInt(frames_seen)); | 670 stack_trace->set_length(Smi::FromInt(frames_seen)); |
662 return stack_trace; | 671 return stack_trace; |
663 } | 672 } |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 if (!property->IsJSArray()) return false; | 1305 if (!property->IsJSArray()) return false; |
1297 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); | 1306 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); |
1298 | 1307 |
1299 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); | 1308 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); |
1300 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); | 1309 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); |
1301 | 1310 |
1302 for (int i = 1; i < elements_limit; i += 4) { | 1311 for (int i = 1; i < elements_limit; i += 4) { |
1303 Handle<JSFunction> fun = | 1312 Handle<JSFunction> fun = |
1304 handle(JSFunction::cast(elements->get(i + 1)), this); | 1313 handle(JSFunction::cast(elements->get(i + 1)), this); |
1305 if (fun->IsFromNativeScript()) continue; | 1314 if (fun->IsFromNativeScript()) continue; |
1306 Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this); | |
1307 Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this); | |
1308 Address pc = code->address() + offset->value(); | |
1309 | 1315 |
1310 Object* script = fun->shared()->script(); | 1316 Object* script = fun->shared()->script(); |
1311 if (script->IsScript() && | 1317 if (script->IsScript() && |
1312 !(Script::cast(script)->source()->IsUndefined())) { | 1318 !(Script::cast(script)->source()->IsUndefined())) { |
1313 int pos = code->SourcePosition(pc); | 1319 int pos = PositionFromStackTrace(elements, i); |
1314 Handle<Script> casted_script(Script::cast(script)); | 1320 Handle<Script> casted_script(Script::cast(script)); |
1315 *target = MessageLocation(casted_script, pos, pos + 1); | 1321 *target = MessageLocation(casted_script, pos, pos + 1); |
1316 return true; | 1322 return true; |
1317 } | 1323 } |
1318 } | 1324 } |
1319 return false; | 1325 return false; |
1320 } | 1326 } |
1321 | 1327 |
1322 | 1328 |
1323 // Traverse prototype chain to find out whether the object is derived from | 1329 // Traverse prototype chain to find out whether the object is derived from |
(...skipping 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2769 if (prev_ && prev_->Intercept(flag)) return true; | 2775 if (prev_ && prev_->Intercept(flag)) return true; |
2770 // Then check whether this scope intercepts. | 2776 // Then check whether this scope intercepts. |
2771 if ((flag & intercept_mask_)) { | 2777 if ((flag & intercept_mask_)) { |
2772 intercepted_flags_ |= flag; | 2778 intercepted_flags_ |= flag; |
2773 return true; | 2779 return true; |
2774 } | 2780 } |
2775 return false; | 2781 return false; |
2776 } | 2782 } |
2777 | 2783 |
2778 } } // namespace v8::internal | 2784 } } // namespace v8::internal |
OLD | NEW |