| 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 "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
| 8 | 8 |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 const Stacktrace& full_stacktrace = Stacktrace::Handle( | 354 const Stacktrace& full_stacktrace = Stacktrace::Handle( |
| 355 Stacktrace::New(full_code_array, full_pc_offset_array)); | 355 Stacktrace::New(full_code_array, full_pc_offset_array)); |
| 356 full_stacktrace.SetCatchStacktrace(full_catch_code_array, | 356 full_stacktrace.SetCatchStacktrace(full_catch_code_array, |
| 357 full_catch_pc_offset_array); | 357 full_catch_pc_offset_array); |
| 358 return full_stacktrace.raw(); | 358 return full_stacktrace.raw(); |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 static void ThrowExceptionHelper(Isolate* isolate, | 362 static void ThrowExceptionHelper(Isolate* isolate, |
| 363 const Instance& incoming_exception, | 363 const Instance& incoming_exception, |
| 364 const Instance& existing_stacktrace, | 364 const Stacktrace& existing_stacktrace, |
| 365 const bool is_rethrow) { | 365 const bool is_rethrow) { |
| 366 bool use_preallocated_stacktrace = false; | 366 bool use_preallocated_stacktrace = false; |
| 367 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); | 367 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); |
| 368 if (exception.IsNull()) { | 368 if (exception.IsNull()) { |
| 369 exception ^= Exceptions::Create(Exceptions::kNullThrown, | 369 exception ^= Exceptions::Create(Exceptions::kNullThrown, |
| 370 Object::empty_array()); | 370 Object::empty_array()); |
| 371 } else if (exception.raw() == isolate->object_store()->out_of_memory() || | 371 } else if (exception.raw() == isolate->object_store()->out_of_memory() || |
| 372 exception.raw() == isolate->object_store()->stack_overflow()) { | 372 exception.raw() == isolate->object_store()->stack_overflow()) { |
| 373 use_preallocated_stacktrace = true; | 373 use_preallocated_stacktrace = true; |
| 374 } | 374 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 BuildStackTrace(isolate, &frame_builder); | 419 BuildStackTrace(isolate, &frame_builder); |
| 420 | 420 |
| 421 // Create arrays for code and pc_offset tuples of each frame. | 421 // Create arrays for code and pc_offset tuples of each frame. |
| 422 code_array = Array::MakeArray(frame_builder.code_list()); | 422 code_array = Array::MakeArray(frame_builder.code_list()); |
| 423 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); | 423 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); |
| 424 } | 424 } |
| 425 if (existing_stacktrace.IsNull()) { | 425 if (existing_stacktrace.IsNull()) { |
| 426 stacktrace = Stacktrace::New(code_array, pc_offset_array); | 426 stacktrace = Stacktrace::New(code_array, pc_offset_array); |
| 427 } else { | 427 } else { |
| 428 ASSERT(is_rethrow); | 428 ASSERT(is_rethrow); |
| 429 stacktrace ^= existing_stacktrace.raw(); | 429 stacktrace = existing_stacktrace.raw(); |
| 430 if (pc_offset_array.Length() != 0) { | 430 if (pc_offset_array.Length() != 0) { |
| 431 // Skip the first frame during a rethrow. This is the catch clause | 431 // Skip the first frame during a rethrow. This is the catch clause |
| 432 // with the rethrow statement, which is not part of the original | 432 // with the rethrow statement, which is not part of the original |
| 433 // trace a rethrow is supposed to preserve. | 433 // trace a rethrow is supposed to preserve. |
| 434 stacktrace.Append(code_array, pc_offset_array, 1); | 434 stacktrace.Append(code_array, pc_offset_array, 1); |
| 435 } | 435 } |
| 436 // Since we are re throwing and appending to the existing stack trace | 436 // Since we are re throwing and appending to the existing stack trace |
| 437 // we clear out the catch trace collected in the existing stack trace | 437 // we clear out the catch trace collected in the existing stack trace |
| 438 // as that trace will not be valid anymore. | 438 // as that trace will not be valid anymore. |
| 439 stacktrace.SetCatchStacktrace(Object::empty_array(), | 439 stacktrace.SetCatchStacktrace(Object::empty_array(), |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 | 566 |
| 567 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { | 567 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { |
| 568 // Do not notify debugger on stack overflow and out of memory exceptions. | 568 // Do not notify debugger on stack overflow and out of memory exceptions. |
| 569 // The VM would crash when the debugger calls back into the VM to | 569 // The VM would crash when the debugger calls back into the VM to |
| 570 // get values of variables. | 570 // get values of variables. |
| 571 if (exception.raw() != isolate->object_store()->out_of_memory() && | 571 if (exception.raw() != isolate->object_store()->out_of_memory() && |
| 572 exception.raw() != isolate->object_store()->stack_overflow()) { | 572 exception.raw() != isolate->object_store()->stack_overflow()) { |
| 573 isolate->debugger()->SignalExceptionThrown(exception); | 573 isolate->debugger()->SignalExceptionThrown(exception); |
| 574 } | 574 } |
| 575 // Null object is a valid exception object. | 575 // Null object is a valid exception object. |
| 576 ThrowExceptionHelper(isolate, exception, Instance::Handle(isolate), false); | 576 ThrowExceptionHelper(isolate, exception, Stacktrace::Handle(isolate), false); |
| 577 } | 577 } |
| 578 | 578 |
| 579 | 579 |
| 580 void Exceptions::ReThrow(Isolate* isolate, | 580 void Exceptions::ReThrow(Isolate* isolate, |
| 581 const Instance& exception, | 581 const Instance& exception, |
| 582 const Instance& stacktrace) { | 582 const Stacktrace& stacktrace) { |
| 583 // Null object is a valid exception object. | 583 // Null object is a valid exception object. |
| 584 ThrowExceptionHelper(isolate, exception, stacktrace, true); | 584 ThrowExceptionHelper(isolate, exception, stacktrace, true); |
| 585 } | 585 } |
| 586 | 586 |
| 587 | 587 |
| 588 void Exceptions::PropagateError(const Error& error) { | 588 void Exceptions::PropagateError(const Error& error) { |
| 589 Isolate* isolate = Isolate::Current(); | 589 Isolate* isolate = Isolate::Current(); |
| 590 ASSERT(isolate->top_exit_frame_info() != 0); | 590 ASSERT(isolate->top_exit_frame_info() != 0); |
| 591 if (error.IsUnhandledException()) { | 591 if (error.IsUnhandledException()) { |
| 592 // If the error object represents an unhandled exception, then | 592 // If the error object represents an unhandled exception, then |
| 593 // rethrow the exception in the normal fashion. | 593 // rethrow the exception in the normal fashion. |
| 594 const UnhandledException& uhe = UnhandledException::Cast(error); | 594 const UnhandledException& uhe = UnhandledException::Cast(error); |
| 595 const Instance& exc = Instance::Handle(isolate, uhe.exception()); | 595 const Instance& exc = Instance::Handle(isolate, uhe.exception()); |
| 596 const Instance& stk = Instance::Handle(isolate, uhe.stacktrace()); | 596 const Stacktrace& stk = Stacktrace::Handle(isolate, uhe.stacktrace()); |
| 597 Exceptions::ReThrow(isolate, exc, stk); | 597 Exceptions::ReThrow(isolate, exc, stk); |
| 598 } else { | 598 } else { |
| 599 // Return to the invocation stub and return this error object. The | 599 // Return to the invocation stub and return this error object. The |
| 600 // C++ code which invoked this dart sequence can check and do the | 600 // C++ code which invoked this dart sequence can check and do the |
| 601 // appropriate thing. | 601 // appropriate thing. |
| 602 uword handler_pc = 0; | 602 uword handler_pc = 0; |
| 603 uword handler_sp = 0; | 603 uword handler_sp = 0; |
| 604 uword handler_fp = 0; | 604 uword handler_fp = 0; |
| 605 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); | 605 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
| 606 JumpToExceptionHandler(isolate, handler_pc, handler_sp, handler_fp, error, | 606 JumpToExceptionHandler(isolate, handler_pc, handler_sp, handler_fp, error, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 | 754 |
| 755 // Throw JavascriptCompatibilityError exception. | 755 // Throw JavascriptCompatibilityError exception. |
| 756 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { | 756 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { |
| 757 const Array& exc_args = Array::Handle(Array::New(1)); | 757 const Array& exc_args = Array::Handle(Array::New(1)); |
| 758 const String& msg_str = String::Handle(String::New(msg)); | 758 const String& msg_str = String::Handle(String::New(msg)); |
| 759 exc_args.SetAt(0, msg_str); | 759 exc_args.SetAt(0, msg_str); |
| 760 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); | 760 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); |
| 761 } | 761 } |
| 762 | 762 |
| 763 } // namespace dart | 763 } // namespace dart |
| OLD | NEW |