| 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 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 const Class& cls, | 406 const Class& cls, |
| 407 const char* field_name, | 407 const char* field_name, |
| 408 const Object& value) { | 408 const Object& value) { |
| 409 const Field& field = Field::Handle(cls.LookupInstanceField( | 409 const Field& field = Field::Handle(cls.LookupInstanceField( |
| 410 String::Handle(Symbols::New(field_name)))); | 410 String::Handle(Symbols::New(field_name)))); |
| 411 ASSERT(!field.IsNull()); | 411 ASSERT(!field.IsNull()); |
| 412 instance.SetField(field, value); | 412 instance.SetField(field, value); |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 // Initialize the fields 'url', 'line', and 'column' in the given instance |
| 417 // according to the given token location in the given script. |
| 418 void Exceptions::SetLocationFields(const Instance& instance, |
| 419 const Class& cls, |
| 420 const Script& script, |
| 421 intptr_t location) { |
| 422 SetField(instance, cls, "url", String::Handle(script.url())); |
| 423 intptr_t line, column; |
| 424 script.GetTokenLocation(location, &line, &column); |
| 425 SetField(instance, cls, "line", Smi::Handle(Smi::New(line))); |
| 426 SetField(instance, cls, "column", Smi::Handle(Smi::New(column))); |
| 427 } |
| 428 |
| 429 |
| 416 // Allocate, initialize, and throw a TypeError. | 430 // Allocate, initialize, and throw a TypeError. |
| 417 void Exceptions::CreateAndThrowTypeError(intptr_t location, | 431 void Exceptions::CreateAndThrowTypeError(intptr_t location, |
| 418 const String& src_type_name, | 432 const String& src_type_name, |
| 419 const String& dst_type_name, | 433 const String& dst_type_name, |
| 420 const String& dst_name, | 434 const String& dst_name, |
| 421 const String& malformed_error) { | 435 const String& malformed_error) { |
| 422 const Array& args = Array::Handle(Array::New(8)); | 436 // Allocate a new instance of TypeError or CastError. |
| 437 Instance& type_error = Instance::Handle(); |
| 438 Class& cls = Class::Handle(); |
| 439 if (dst_name.Equals(kCastErrorDstName)) { |
| 440 type_error = NewInstance("CastErrorImplementation"); |
| 441 cls = type_error.clazz(); |
| 442 cls = cls.SuperClass(); |
| 443 } else { |
| 444 type_error = NewInstance("TypeErrorImplementation"); |
| 445 cls = type_error.clazz(); |
| 446 } |
| 423 | 447 |
| 424 ExceptionType exception_type = | 448 // Initialize 'url', 'line', and 'column' fields. |
| 425 dst_name.Equals(kCastErrorDstName) ? kCast : kType; | 449 DartFrameIterator iterator; |
| 450 const Script& script = Script::Handle(GetCallerScript(&iterator)); |
| 451 // Location fields are defined in AssertionError, the superclass of TypeError. |
| 452 const Class& assertion_error_class = Class::Handle(cls.SuperClass()); |
| 453 SetLocationFields(type_error, assertion_error_class, script, location); |
| 426 | 454 |
| 427 // Initialize argument 'failedAssertion'. | 455 // Initialize field 'failedAssertion' in AssertionError superclass. |
| 428 // Printing the src_obj value would be possible, but ToString() is expensive | 456 // Printing the src_obj value would be possible, but ToString() is expensive |
| 429 // and not meaningful for all classes, so we just print '$expr instanceof...'. | 457 // and not meaningful for all classes, so we just print '$expr instanceof...'. |
| 430 // Users should look at TypeError.ToString(), which contains more useful | 458 // Users should look at TypeError.ToString(), which contains more useful |
| 431 // information than AssertionError.failedAssertion. | 459 // information than AssertionError.failedAssertion. |
| 432 String& failed_assertion = String::Handle(String::New("$expr instanceof ")); | 460 String& failed_assertion = String::Handle(String::New("$expr instanceof ")); |
| 433 failed_assertion = String::Concat(failed_assertion, dst_type_name); | 461 failed_assertion = String::Concat(failed_assertion, dst_type_name); |
| 434 args.SetAt(0, failed_assertion); | 462 SetField(type_error, |
| 463 assertion_error_class, |
| 464 "failedAssertion", |
| 465 failed_assertion); |
| 435 | 466 |
| 436 // Initialize 'url', 'line', and 'column' arguments. | 467 // Initialize field 'srcType'. |
| 437 DartFrameIterator iterator; | 468 SetField(type_error, cls, "srcType", src_type_name); |
| 438 const Script& script = Script::Handle(GetCallerScript(&iterator)); | |
| 439 intptr_t line, column; | |
| 440 script.GetTokenLocation(location, &line, &column); | |
| 441 args.SetAt(1, String::Handle(script.url())); | |
| 442 args.SetAt(2, Smi::Handle(Smi::New(line))); | |
| 443 args.SetAt(3, Smi::Handle(Smi::New(column))); | |
| 444 | 469 |
| 445 // Initialize argument 'srcType'. | 470 // Initialize field 'dstType'. |
| 446 args.SetAt(4, src_type_name); | 471 SetField(type_error, cls, "dstType", dst_type_name); |
| 447 args.SetAt(5, dst_type_name); | 472 |
| 448 args.SetAt(6, dst_name); | 473 // Initialize field 'dstName'. |
| 449 args.SetAt(7, malformed_error); | 474 SetField(type_error, cls, "dstName", dst_name); |
| 475 |
| 476 // Initialize field 'malformedError'. |
| 477 SetField(type_error, cls, "malformedError", malformed_error); |
| 450 | 478 |
| 451 // Type errors in the core library may be difficult to diagnose. | 479 // Type errors in the core library may be difficult to diagnose. |
| 452 // Print type error information before throwing the error when debugging. | 480 // Print type error information before throwing the error when debugging. |
| 453 if (FLAG_print_stacktrace_at_throw) { | 481 if (FLAG_print_stacktrace_at_throw) { |
| 454 if (!malformed_error.IsNull()) { | 482 if (!malformed_error.IsNull()) { |
| 455 OS::Print("%s\n", malformed_error.ToCString()); | 483 OS::Print("%s\n", malformed_error.ToCString()); |
| 456 } | 484 } |
| 457 intptr_t line, column; | 485 intptr_t line, column; |
| 458 script.GetTokenLocation(location, &line, &column); | 486 script.GetTokenLocation(location, &line, &column); |
| 459 OS::Print("'%s': Failed type check: line %"Pd" pos %"Pd": ", | 487 OS::Print("'%s': Failed type check: line %"Pd" pos %"Pd": ", |
| 460 String::Handle(script.url()).ToCString(), line, column); | 488 String::Handle(script.url()).ToCString(), line, column); |
| 461 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { | 489 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { |
| 462 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", | 490 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", |
| 463 src_type_name.ToCString(), | 491 src_type_name.ToCString(), |
| 464 dst_type_name.ToCString(), | 492 dst_type_name.ToCString(), |
| 465 dst_name.ToCString()); | 493 dst_name.ToCString()); |
| 466 } else { | 494 } else { |
| 467 OS::Print("malformed type used.\n"); | 495 OS::Print("malformed type used.\n"); |
| 468 } | 496 } |
| 469 } | 497 } |
| 470 // Throw TypeError instance. | 498 // Throw TypeError instance. |
| 471 Exceptions::ThrowByType(exception_type, args); | 499 Exceptions::Throw(type_error); |
| 472 UNREACHABLE(); | 500 UNREACHABLE(); |
| 473 } | 501 } |
| 474 | 502 |
| 475 | 503 |
| 476 void Exceptions::Throw(const Instance& exception) { | 504 void Exceptions::Throw(const Instance& exception) { |
| 477 Isolate* isolate = Isolate::Current(); | 505 Isolate* isolate = Isolate::Current(); |
| 478 isolate->debugger()->SignalExceptionThrown(exception); | 506 isolate->debugger()->SignalExceptionThrown(exception); |
| 479 // Null object is a valid exception object. | 507 // Null object is a valid exception object. |
| 480 ThrowExceptionHelper(exception, Instance::Handle(isolate)); | 508 ThrowExceptionHelper(exception, Instance::Handle(isolate)); |
| 481 } | 509 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 class_name = &Symbols::IsolateSpawnException(); | 619 class_name = &Symbols::IsolateSpawnException(); |
| 592 break; | 620 break; |
| 593 case kIsolateUnhandledException: | 621 case kIsolateUnhandledException: |
| 594 library = Library::IsolateLibrary(); | 622 library = Library::IsolateLibrary(); |
| 595 class_name = &Symbols::IsolateUnhandledException(); | 623 class_name = &Symbols::IsolateUnhandledException(); |
| 596 break; | 624 break; |
| 597 case kFiftyThreeBitOverflowError: | 625 case kFiftyThreeBitOverflowError: |
| 598 library = Library::CoreLibrary(); | 626 library = Library::CoreLibrary(); |
| 599 class_name = &Symbols::FiftyThreeBitOverflowError(); | 627 class_name = &Symbols::FiftyThreeBitOverflowError(); |
| 600 break; | 628 break; |
| 601 case kAssertion: | |
| 602 library = Library::CoreLibrary(); | |
| 603 class_name = &Symbols::AssertionError(); | |
| 604 break; | |
| 605 case kCast: | |
| 606 library = Library::CoreLibrary(); | |
| 607 class_name = &Symbols::CastError(); | |
| 608 break; | |
| 609 case kType: | |
| 610 library = Library::CoreLibrary(); | |
| 611 class_name = &Symbols::TypeError(); | |
| 612 break; | |
| 613 case kFallThrough: | |
| 614 library = Library::CoreLibrary(); | |
| 615 class_name = &Symbols::FallThroughError(); | |
| 616 break; | |
| 617 case kAbstractClassInstantiation: | |
| 618 library = Library::CoreLibrary(); | |
| 619 class_name = &Symbols::AbstractClassInstantiationError(); | |
| 620 break; | |
| 621 } | 629 } |
| 622 | 630 |
| 623 return DartLibraryCalls::ExceptionCreate(library, | 631 return DartLibraryCalls::ExceptionCreate(library, |
| 624 *class_name, | 632 *class_name, |
| 625 *constructor_name, | 633 *constructor_name, |
| 626 arguments); | 634 arguments); |
| 627 } | 635 } |
| 628 | 636 |
| 629 } // namespace dart | 637 } // namespace dart |
| OLD | NEW |