| 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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 } | 405 } |
| 406 } else { | 406 } else { |
| 407 // Get stacktrace field of class Error. | 407 // Get stacktrace field of class Error. |
| 408 const Field& stacktrace_field = | 408 const Field& stacktrace_field = |
| 409 Field::Handle(isolate, LookupStacktraceField(exception)); | 409 Field::Handle(isolate, LookupStacktraceField(exception)); |
| 410 handler_exists = FindExceptionHandler(isolate, | 410 handler_exists = FindExceptionHandler(isolate, |
| 411 &handler_pc, | 411 &handler_pc, |
| 412 &handler_sp, | 412 &handler_sp, |
| 413 &handler_fp, | 413 &handler_fp, |
| 414 &handler_needs_stacktrace); | 414 &handler_needs_stacktrace); |
| 415 Array& code_array = Array::Handle(isolate, Object::empty_array().raw()); | 415 if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { |
| 416 Array& pc_offset_array = | 416 Array& code_array = Array::Handle(isolate, Object::empty_array().raw()); |
| 417 Array::Handle(isolate, Object::empty_array().raw()); | 417 Array& pc_offset_array = |
| 418 // If we have an error with a stacktrace field then collect the full stack | 418 Array::Handle(isolate, Object::empty_array().raw()); |
| 419 // trace and store it into the field. | 419 // If we have an error with a stacktrace field then collect the full stack |
| 420 if (!stacktrace_field.IsNull()) { | 420 // trace and store it into the field. |
| 421 if (exception.GetField(stacktrace_field) == Object::null()) { | 421 if (!stacktrace_field.IsNull()) { |
| 422 // This is an error object and we need to capture the full stack trace | 422 if (exception.GetField(stacktrace_field) == Object::null()) { |
| 423 // here implicitly, so we set up the stack trace. The stack trace | 423 // This is an error object and we need to capture the full stack trace |
| 424 // field is set only once, it is not overriden. | 424 // here implicitly, so we set up the stack trace. The stack trace |
| 425 const Stacktrace& full_stacktrace = | 425 // field is set only once, it is not overriden. |
| 426 Stacktrace::Handle(isolate, Exceptions::CurrentStacktrace()); | 426 const Stacktrace& full_stacktrace = |
| 427 exception.SetField(stacktrace_field, full_stacktrace); | 427 Stacktrace::Handle(isolate, Exceptions::CurrentStacktrace()); |
| 428 exception.SetField(stacktrace_field, full_stacktrace); |
| 429 } |
| 428 } | 430 } |
| 429 } | 431 if (handler_needs_stacktrace) { |
| 430 if (handler_needs_stacktrace) { | 432 RegularStacktraceBuilder frame_builder(false); |
| 431 RegularStacktraceBuilder frame_builder(false); | 433 BuildStackTrace(isolate, &frame_builder); |
| 432 BuildStackTrace(isolate, &frame_builder); | |
| 433 | 434 |
| 434 // Create arrays for code and pc_offset tuples of each frame. | 435 // Create arrays for code and pc_offset tuples of each frame. |
| 435 code_array = Array::MakeArray(frame_builder.code_list()); | 436 code_array = Array::MakeArray(frame_builder.code_list()); |
| 436 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); | 437 pc_offset_array = Array::MakeArray(frame_builder.pc_offset_list()); |
| 437 } | |
| 438 if (existing_stacktrace.IsNull()) { | |
| 439 stacktrace = Stacktrace::New(code_array, pc_offset_array); | |
| 440 } else { | |
| 441 ASSERT(is_rethrow); | |
| 442 stacktrace ^= existing_stacktrace.raw(); | |
| 443 if (pc_offset_array.Length() != 0) { | |
| 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 stacktrace.Append(code_array, pc_offset_array, 1); | |
| 448 } | 438 } |
| 449 // Since we are re throwing and appending to the existing stack trace | 439 if (existing_stacktrace.IsNull()) { |
| 450 // we clear out the catch trace collected in the existing stack trace | 440 stacktrace = Stacktrace::New(code_array, pc_offset_array); |
| 451 // as that trace will not be valid anymore. | 441 } else { |
| 452 stacktrace.SetCatchStacktrace(Object::empty_array(), | 442 ASSERT(is_rethrow); |
| 453 Object::empty_array()); | 443 stacktrace ^= existing_stacktrace.raw(); |
| 444 if (pc_offset_array.Length() != 0) { |
| 445 // Skip the first frame during a rethrow. This is the catch clause |
| 446 // with the rethrow statement, which is not part of the original |
| 447 // trace a rethrow is supposed to preserve. |
| 448 stacktrace.Append(code_array, pc_offset_array, 1); |
| 449 } |
| 450 // Since we are re throwing and appending to the existing stack trace |
| 451 // we clear out the catch trace collected in the existing stack trace |
| 452 // as that trace will not be valid anymore. |
| 453 stacktrace.SetCatchStacktrace(Object::empty_array(), |
| 454 Object::empty_array()); |
| 455 } |
| 454 } | 456 } |
| 455 } | 457 } |
| 456 // We expect to find a handler_pc, if the exception is unhandled | 458 // We expect to find a handler_pc, if the exception is unhandled |
| 457 // then we expect to at least have the dart entry frame on the | 459 // then we expect to at least have the dart entry frame on the |
| 458 // stack as Exceptions::Throw should happen only after a dart | 460 // stack as Exceptions::Throw should happen only after a dart |
| 459 // invocation has been done. | 461 // invocation has been done. |
| 460 ASSERT(handler_pc != 0); | 462 ASSERT(handler_pc != 0); |
| 461 | 463 |
| 462 if (FLAG_print_stacktrace_at_throw) { | 464 if (FLAG_print_stacktrace_at_throw) { |
| 463 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); | 465 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 | 750 |
| 749 // Throw JavascriptCompatibilityError exception. | 751 // Throw JavascriptCompatibilityError exception. |
| 750 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { | 752 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { |
| 751 const Array& exc_args = Array::Handle(Array::New(1)); | 753 const Array& exc_args = Array::Handle(Array::New(1)); |
| 752 const String& msg_str = String::Handle(String::New(msg)); | 754 const String& msg_str = String::Handle(String::New(msg)); |
| 753 exc_args.SetAt(0, msg_str); | 755 exc_args.SetAt(0, msg_str); |
| 754 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); | 756 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); |
| 755 } | 757 } |
| 756 | 758 |
| 757 } // namespace dart | 759 } // namespace dart |
| OLD | NEW |