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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 } else if (exception.raw() == isolate->object_store()->out_of_memory() || | 374 } else if (exception.raw() == isolate->object_store()->out_of_memory() || |
375 exception.raw() == isolate->object_store()->stack_overflow()) { | 375 exception.raw() == isolate->object_store()->stack_overflow()) { |
376 use_preallocated_stacktrace = true; | 376 use_preallocated_stacktrace = true; |
377 } | 377 } |
378 uword handler_pc = 0; | 378 uword handler_pc = 0; |
379 uword handler_sp = 0; | 379 uword handler_sp = 0; |
380 uword handler_fp = 0; | 380 uword handler_fp = 0; |
381 Instance& stacktrace = Instance::Handle(zone); | 381 Instance& stacktrace = Instance::Handle(zone); |
382 bool handler_exists = false; | 382 bool handler_exists = false; |
383 bool handler_needs_stacktrace = false; | 383 bool handler_needs_stacktrace = false; |
| 384 // Find the exception handler and determine if the handler needs a |
| 385 // stacktrace. |
| 386 handler_exists = FindExceptionHandler(thread, &handler_pc, &handler_sp, |
| 387 &handler_fp, &handler_needs_stacktrace); |
384 if (use_preallocated_stacktrace) { | 388 if (use_preallocated_stacktrace) { |
385 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); | |
386 PreallocatedStacktraceBuilder frame_builder(stacktrace); | |
387 handler_exists = | |
388 FindExceptionHandler(thread, &handler_pc, &handler_sp, &handler_fp, | |
389 &handler_needs_stacktrace); | |
390 if (handler_pc == 0) { | 389 if (handler_pc == 0) { |
391 // No Dart frame. | 390 // No Dart frame. |
392 ASSERT(incoming_exception.raw() == | 391 ASSERT(incoming_exception.raw() == |
393 isolate->object_store()->out_of_memory()); | 392 isolate->object_store()->out_of_memory()); |
394 const UnhandledException& error = UnhandledException::Handle( | 393 const UnhandledException& error = UnhandledException::Handle( |
395 zone, isolate->object_store()->preallocated_unhandled_exception()); | 394 zone, isolate->object_store()->preallocated_unhandled_exception()); |
396 thread->long_jump_base()->Jump(1, error); | 395 thread->long_jump_base()->Jump(1, error); |
397 UNREACHABLE(); | 396 UNREACHABLE(); |
398 } | 397 } |
| 398 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); |
| 399 PreallocatedStacktraceBuilder frame_builder(stacktrace); |
399 if (handler_needs_stacktrace) { | 400 if (handler_needs_stacktrace) { |
400 BuildStackTrace(&frame_builder); | 401 BuildStackTrace(&frame_builder); |
401 } | 402 } |
402 } else { | 403 } else { |
403 // Get stacktrace field of class Error. This is needed to determine whether | |
404 // we have a subclass of Error which carries around its stack trace. | |
405 const Field& stacktrace_field = | |
406 Field::Handle(zone, LookupStacktraceField(exception)); | |
407 | |
408 // Find the exception handler and determine if the handler needs a | |
409 // stacktrace. | |
410 handler_exists = | |
411 FindExceptionHandler(thread, &handler_pc, &handler_sp, &handler_fp, | |
412 &handler_needs_stacktrace); | |
413 if (!existing_stacktrace.IsNull()) { | 404 if (!existing_stacktrace.IsNull()) { |
414 // If we have an existing stack trace then this better be a rethrow. The | 405 // If we have an existing stack trace then this better be a rethrow. The |
415 // reverse is not necessarily true (e.g. Dart_PropagateError can cause | 406 // reverse is not necessarily true (e.g. Dart_PropagateError can cause |
416 // a rethrow being called without an existing stacktrace.) | 407 // a rethrow being called without an existing stacktrace.) |
417 ASSERT(is_rethrow); | 408 ASSERT(is_rethrow); |
418 ASSERT(stacktrace_field.IsNull() || | |
419 (exception.GetField(stacktrace_field) != Object::null())); | |
420 stacktrace = existing_stacktrace.raw(); | 409 stacktrace = existing_stacktrace.raw(); |
421 } else if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { | 410 } else { |
422 // Collect the stacktrace if needed. | 411 // Get stacktrace field of class Error to determine whether we have a |
423 ASSERT(existing_stacktrace.IsNull()); | 412 // subclass of Error which carries around its stack trace. |
424 stacktrace = Exceptions::CurrentStacktrace(); | 413 const Field& stacktrace_field = |
425 // If we have an Error object, then set its stackTrace field only if it | 414 Field::Handle(zone, LookupStacktraceField(exception)); |
426 // not yet initialized. | 415 if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { |
427 if (!stacktrace_field.IsNull() && | 416 // Collect the stacktrace if needed. |
428 (exception.GetField(stacktrace_field) == Object::null())) { | 417 ASSERT(existing_stacktrace.IsNull()); |
429 exception.SetField(stacktrace_field, stacktrace); | 418 stacktrace = Exceptions::CurrentStacktrace(); |
| 419 // If we have an Error object, then set its stackTrace field only if it |
| 420 // not yet initialized. |
| 421 if (!stacktrace_field.IsNull() && |
| 422 (exception.GetField(stacktrace_field) == Object::null())) { |
| 423 exception.SetField(stacktrace_field, stacktrace); |
| 424 } |
430 } | 425 } |
431 } | 426 } |
432 } | 427 } |
433 // We expect to find a handler_pc, if the exception is unhandled | 428 // We expect to find a handler_pc, if the exception is unhandled |
434 // then we expect to at least have the dart entry frame on the | 429 // then we expect to at least have the dart entry frame on the |
435 // stack as Exceptions::Throw should happen only after a dart | 430 // stack as Exceptions::Throw should happen only after a dart |
436 // invocation has been done. | 431 // invocation has been done. |
437 ASSERT(handler_pc != 0); | 432 ASSERT(handler_pc != 0); |
438 | 433 |
439 if (FLAG_print_stacktrace_at_throw) { | 434 if (FLAG_print_stacktrace_at_throw) { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 class_name = &Symbols::_CompileTimeError(); | 783 class_name = &Symbols::_CompileTimeError(); |
789 break; | 784 break; |
790 } | 785 } |
791 | 786 |
792 return DartLibraryCalls::InstanceCreate(library, *class_name, | 787 return DartLibraryCalls::InstanceCreate(library, *class_name, |
793 *constructor_name, arguments); | 788 *constructor_name, arguments); |
794 } | 789 } |
795 | 790 |
796 | 791 |
797 } // namespace dart | 792 } // namespace dart |
OLD | NEW |