Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/exceptions.h" | 5 #include "vm/exceptions.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 const Stacktrace& full_stacktrace = Stacktrace::Handle( | 368 const Stacktrace& full_stacktrace = Stacktrace::Handle( |
| 369 Stacktrace::New(full_code_array, full_pc_offset_array)); | 369 Stacktrace::New(full_code_array, full_pc_offset_array)); |
| 370 full_stacktrace.SetCatchStacktrace(full_catch_code_array, | 370 full_stacktrace.SetCatchStacktrace(full_catch_code_array, |
| 371 full_catch_pc_offset_array); | 371 full_catch_pc_offset_array); |
| 372 return full_stacktrace.raw(); | 372 return full_stacktrace.raw(); |
| 373 } | 373 } |
| 374 | 374 |
| 375 | 375 |
| 376 static void ThrowExceptionHelper(Isolate* isolate, | 376 static void ThrowExceptionHelper(Isolate* isolate, |
| 377 const Instance& incoming_exception, | 377 const Instance& incoming_exception, |
| 378 const Instance& existing_stacktrace) { | 378 const Instance& existing_stacktrace, |
| 379 const bool is_rethrow) { | |
| 380 ASSERT(existing_stacktrace.IsNull() == !is_rethrow); | |
| 379 bool use_preallocated_stacktrace = false; | 381 bool use_preallocated_stacktrace = false; |
| 380 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); | 382 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); |
| 381 if (exception.IsNull()) { | 383 if (exception.IsNull()) { |
| 382 exception ^= Exceptions::Create(Exceptions::kNullThrown, | 384 exception ^= Exceptions::Create(Exceptions::kNullThrown, |
| 383 Object::empty_array()); | 385 Object::empty_array()); |
| 384 } else if (exception.raw() == isolate->object_store()->out_of_memory() || | 386 } else if (exception.raw() == isolate->object_store()->out_of_memory() || |
| 385 exception.raw() == isolate->object_store()->stack_overflow()) { | 387 exception.raw() == isolate->object_store()->stack_overflow()) { |
| 386 use_preallocated_stacktrace = true; | 388 use_preallocated_stacktrace = true; |
| 387 } | 389 } |
| 388 uword handler_pc = 0; | 390 uword handler_pc = 0; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 if (handler_needs_stacktrace) { | 431 if (handler_needs_stacktrace) { |
| 430 RegularStacktraceBuilder frame_builder(false); | 432 RegularStacktraceBuilder frame_builder(false); |
| 431 BuildStackTrace(isolate, &frame_builder); | 433 BuildStackTrace(isolate, &frame_builder); |
| 432 | 434 |
| 433 // Create arrays for code and pc_offset tuples of each frame. | 435 // Create arrays for code and pc_offset tuples of each frame. |
| 434 code_array = Array::MakeArray(frame_builder.code_list()); | 436 code_array = Array::MakeArray(frame_builder.code_list()); |
| 435 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); | 437 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); |
| 436 } | 438 } |
| 437 if (existing_stacktrace.IsNull()) { | 439 if (existing_stacktrace.IsNull()) { |
| 438 stacktrace = Stacktrace::New(code_array, pc_offset_array); | 440 stacktrace = Stacktrace::New(code_array, pc_offset_array); |
| 439 } else { | 441 } else { |
|
siva
2014/06/25 22:46:12
How about moving the assert on top to here as
ASSE
| |
| 440 stacktrace ^= existing_stacktrace.raw(); | 442 stacktrace ^= existing_stacktrace.raw(); |
| 441 if (pc_offset_array.Length() != 0) { | 443 if (pc_offset_array.Length() != 0) { |
| 442 stacktrace.Append(code_array, pc_offset_array); | 444 // Skip the first frame during a rethrow. This is the catch clause with |
| 445 // the rethrow statement, which is not part of the original trace a | |
| 446 // rethrow is supposed to preserve. | |
| 447 const intptr_t offset = is_rethrow ? 1 : 0; | |
|
siva
2014/06/25 22:46:12
Can this just be:
const intptr_t offset = 1;
since
rmacnak
2014/06/25 23:00:43
Ah, yes.
| |
| 448 stacktrace.Append(code_array, pc_offset_array, offset); | |
| 443 } | 449 } |
| 444 // Since we are re throwing and appending to the existing stack trace | 450 // Since we are re throwing and appending to the existing stack trace |
| 445 // we clear out the catch trace collected in the existing stack trace | 451 // we clear out the catch trace collected in the existing stack trace |
| 446 // as that trace will not be valid anymore. | 452 // as that trace will not be valid anymore. |
| 447 stacktrace.SetCatchStacktrace(Object::empty_array(), | 453 stacktrace.SetCatchStacktrace(Object::empty_array(), |
| 448 Object::empty_array()); | 454 Object::empty_array()); |
| 449 } | 455 } |
| 450 } | 456 } |
| 451 // We expect to find a handler_pc, if the exception is unhandled | 457 // We expect to find a handler_pc, if the exception is unhandled |
| 452 // then we expect to at least have the dart entry frame on the | 458 // then we expect to at least have the dart entry frame on the |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 } | 573 } |
| 568 // Throw TypeError or CastError instance. | 574 // Throw TypeError or CastError instance. |
| 569 Exceptions::ThrowByType(exception_type, args); | 575 Exceptions::ThrowByType(exception_type, args); |
| 570 UNREACHABLE(); | 576 UNREACHABLE(); |
| 571 } | 577 } |
| 572 | 578 |
| 573 | 579 |
| 574 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { | 580 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { |
| 575 isolate->debugger()->SignalExceptionThrown(exception); | 581 isolate->debugger()->SignalExceptionThrown(exception); |
| 576 // Null object is a valid exception object. | 582 // Null object is a valid exception object. |
| 577 ThrowExceptionHelper(isolate, exception, Instance::Handle(isolate)); | 583 ThrowExceptionHelper(isolate, exception, Instance::Handle(isolate), false); |
| 578 } | 584 } |
| 579 | 585 |
| 580 | 586 |
| 581 void Exceptions::ReThrow(Isolate* isolate, | 587 void Exceptions::ReThrow(Isolate* isolate, |
| 582 const Instance& exception, | 588 const Instance& exception, |
| 583 const Instance& stacktrace) { | 589 const Instance& stacktrace) { |
| 584 // Null object is a valid exception object. | 590 // Null object is a valid exception object. |
| 585 ThrowExceptionHelper(isolate, exception, stacktrace); | 591 ThrowExceptionHelper(isolate, exception, stacktrace, true); |
| 586 } | 592 } |
| 587 | 593 |
| 588 | 594 |
| 589 void Exceptions::PropagateError(const Error& error) { | 595 void Exceptions::PropagateError(const Error& error) { |
| 590 Isolate* isolate = Isolate::Current(); | 596 Isolate* isolate = Isolate::Current(); |
| 591 ASSERT(isolate->top_exit_frame_info() != 0); | 597 ASSERT(isolate->top_exit_frame_info() != 0); |
| 592 if (error.IsUnhandledException()) { | 598 if (error.IsUnhandledException()) { |
| 593 // If the error object represents an unhandled exception, then | 599 // If the error object represents an unhandled exception, then |
| 594 // rethrow the exception in the normal fashion. | 600 // rethrow the exception in the normal fashion. |
| 595 const UnhandledException& uhe = UnhandledException::Cast(error); | 601 const UnhandledException& uhe = UnhandledException::Cast(error); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 | 749 |
| 744 // Throw JavascriptCompatibilityError exception. | 750 // Throw JavascriptCompatibilityError exception. |
| 745 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { | 751 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { |
| 746 const Array& exc_args = Array::Handle(Array::New(1)); | 752 const Array& exc_args = Array::Handle(Array::New(1)); |
| 747 const String& msg_str = String::Handle(String::New(msg)); | 753 const String& msg_str = String::Handle(String::New(msg)); |
| 748 exc_args.SetAt(0, msg_str); | 754 exc_args.SetAt(0, msg_str); |
| 749 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); | 755 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); |
| 750 } | 756 } |
| 751 | 757 |
| 752 } // namespace dart | 758 } // namespace dart |
| OLD | NEW |