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" |
11 #include "vm/debugger.h" | 11 #include "vm/debugger.h" |
12 #include "vm/flags.h" | 12 #include "vm/flags.h" |
13 #include "vm/object.h" | 13 #include "vm/object.h" |
14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
18 #include "vm/tags.h" | 18 #include "vm/tags.h" |
19 | 19 |
20 namespace dart { | 20 namespace dart { |
21 | 21 |
22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, | 22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
23 "Prints a stack trace everytime a throw occurs."); | 23 "Prints a stack trace everytime a throw occurs."); |
24 | 24 |
25 | 25 |
26 const char* Exceptions::kCastErrorDstName = "type cast"; | |
27 | |
28 | |
29 class StacktraceBuilder : public ValueObject { | 26 class StacktraceBuilder : public ValueObject { |
30 public: | 27 public: |
31 StacktraceBuilder() { } | 28 StacktraceBuilder() { } |
32 virtual ~StacktraceBuilder() { } | 29 virtual ~StacktraceBuilder() { } |
33 | 30 |
34 virtual void AddFrame(const Code& code, const Smi& offset) = 0; | 31 virtual void AddFrame(const Code& code, const Smi& offset) = 0; |
35 }; | 32 }; |
36 | 33 |
37 | 34 |
38 class RegularStacktraceBuilder : public StacktraceBuilder { | 35 class RegularStacktraceBuilder : public StacktraceBuilder { |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); | 424 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); |
428 ASSERT(!cls.IsNull()); | 425 ASSERT(!cls.IsNull()); |
429 // There are no parameterized error types, so no need to set type arguments. | 426 // There are no parameterized error types, so no need to set type arguments. |
430 return Instance::New(cls); | 427 return Instance::New(cls); |
431 } | 428 } |
432 | 429 |
433 | 430 |
434 // Allocate, initialize, and throw a TypeError or CastError. | 431 // Allocate, initialize, and throw a TypeError or CastError. |
435 // If error_msg is not null, throw a TypeError, even for a type cast. | 432 // If error_msg is not null, throw a TypeError, even for a type cast. |
436 void Exceptions::CreateAndThrowTypeError(TokenPosition location, | 433 void Exceptions::CreateAndThrowTypeError(TokenPosition location, |
437 const String& src_type_name, | 434 const AbstractType& src_type, |
438 const String& dst_type_name, | 435 const AbstractType& dst_type, |
439 const String& dst_name, | 436 const String& dst_name, |
440 const String& error_msg) { | 437 const String& bound_error_msg) { |
441 const Array& args = Array::Handle(Array::New(7)); | 438 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead. |
439 Zone* zone = Thread::Current()->zone(); | |
440 const Array& args = Array::Handle(zone, Array::New(4)); | |
442 | 441 |
443 ExceptionType exception_type = | 442 ExceptionType exception_type = |
444 (error_msg.IsNull() && dst_name.Equals(kCastErrorDstName)) ? | 443 (bound_error_msg.IsNull() && |
445 kCast : kType; | 444 (dst_name.raw() == Symbols::InTypeCast().raw())) ? kCast : kType; |
446 | 445 |
447 DartFrameIterator iterator; | 446 DartFrameIterator iterator; |
448 const Script& script = Script::Handle(GetCallerScript(&iterator)); | 447 const Script& script = Script::Handle(zone, GetCallerScript(&iterator)); |
449 intptr_t line; | 448 intptr_t line; |
450 intptr_t column = -1; | 449 intptr_t column = -1; |
451 if (script.HasSource()) { | 450 if (script.HasSource()) { |
452 script.GetTokenLocation(location, &line, &column); | 451 script.GetTokenLocation(location, &line, &column); |
453 } else { | 452 } else { |
454 script.GetTokenLocation(location, &line, NULL); | 453 script.GetTokenLocation(location, &line, NULL); |
455 } | 454 } |
456 // Initialize '_url', '_line', and '_column' arguments. | 455 // Initialize '_url', '_line', and '_column' arguments. |
457 args.SetAt(0, String::Handle(script.url())); | 456 args.SetAt(0, String::Handle(zone, script.url())); |
458 args.SetAt(1, Smi::Handle(Smi::New(line))); | 457 args.SetAt(1, Smi::Handle(zone, Smi::New(line))); |
459 args.SetAt(2, Smi::Handle(Smi::New(column))); | 458 args.SetAt(2, Smi::Handle(zone, Smi::New(column))); |
460 | 459 |
461 // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. | 460 // Construct '_errorMsg'. |
462 args.SetAt(3, src_type_name); | 461 GrowableHandlePtrArray<const String> pieces(zone, 20); |
463 args.SetAt(4, dst_type_name); | 462 |
464 args.SetAt(5, dst_name); | 463 // Print bound error first, if any. |
465 args.SetAt(6, error_msg); | 464 if (!bound_error_msg.IsNull() && (bound_error_msg.Length() > 0)) { |
465 pieces.Add(bound_error_msg); | |
466 pieces.Add(Symbols::NewLine()); | |
467 } | |
468 | |
469 // If dst_type is malformed or malbounded, only print the embedded error. | |
470 if (!dst_type.IsNull()) { | |
471 const LanguageError& error = LanguageError::Handle(zone, dst_type.error()); | |
472 if (!error.IsNull()) { | |
473 // Print the embedded error only. | |
474 pieces.Add(String::Handle(zone, Symbols::New(error.ToErrorCString()))); | |
475 pieces.Add(Symbols::NewLine()); | |
476 } else { | |
477 // Describe the type error. | |
478 if (!src_type.IsNull()) { | |
479 pieces.Add(Symbols::TypeQuote()); | |
480 pieces.Add(String::Handle(zone, src_type.UserVisibleName())); | |
481 pieces.Add(Symbols::QuoteIsNotASubtypeOf()); | |
482 } | |
483 pieces.Add(Symbols::TypeQuote()); | |
484 pieces.Add(String::Handle(zone, dst_type.UserVisibleName())); | |
485 pieces.Add(Symbols::SingleQuote()); | |
486 if (exception_type == kCast) { | |
487 pieces.Add(dst_name); | |
488 } else if (dst_name.Length() > 0) { | |
489 pieces.Add(Symbols::SpaceOfSpace()); | |
490 pieces.Add(Symbols::SingleQuote()); | |
491 pieces.Add(dst_name); | |
492 pieces.Add(Symbols::SingleQuote()); | |
493 } | |
494 // Print URIs of src and dst types. | |
495 pieces.Add(Symbols::SpaceWhereNewLine()); | |
496 if (!src_type.IsNull()) { | |
497 pieces.Add(String::Handle(zone, src_type.EnumerateURIs())); | |
498 } | |
499 if (!dst_type.IsDynamicType() && !dst_type.IsVoidType()) { | |
500 pieces.Add(String::Handle(zone, dst_type.EnumerateURIs())); | |
501 } | |
502 } | |
503 } | |
504 const String& error_msg = | |
505 String::Handle(zone, Symbols::FromConcatAll(pieces)); | |
506 args.SetAt(3, error_msg); | |
466 | 507 |
467 // Type errors in the core library may be difficult to diagnose. | 508 // Type errors in the core library may be difficult to diagnose. |
468 // Print type error information before throwing the error when debugging. | 509 // Print type error information before throwing the error when debugging. |
469 if (FLAG_print_stacktrace_at_throw) { | 510 if (FLAG_print_stacktrace_at_throw) { |
470 if (!error_msg.IsNull()) { | |
471 OS::Print("%s\n", error_msg.ToCString()); | |
472 } | |
473 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", | 511 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", |
474 String::Handle(script.url()).ToCString(), line, column); | 512 String::Handle(zone, script.url()).ToCString(), line, column); |
475 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { | 513 OS::Print("%s\n", error_msg.ToCString()); |
srdjan
2016/03/09 22:38:23
Replace OS::Print with THR_Print
regis
2016/03/09 23:15:40
Done.
| |
476 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", | |
477 src_type_name.ToCString(), | |
478 dst_type_name.ToCString(), | |
479 dst_name.ToCString()); | |
480 } else { | |
481 OS::Print("type error.\n"); | |
482 } | |
483 } | 514 } |
484 | 515 |
485 // Throw TypeError or CastError instance. | 516 // Throw TypeError or CastError instance. |
486 Exceptions::ThrowByType(exception_type, args); | 517 Exceptions::ThrowByType(exception_type, args); |
487 UNREACHABLE(); | 518 UNREACHABLE(); |
488 } | 519 } |
489 | 520 |
490 | 521 |
491 void Exceptions::Throw(Thread* thread, const Instance& exception) { | 522 void Exceptions::Throw(Thread* thread, const Instance& exception) { |
492 // Do not notify debugger on stack overflow and out of memory exceptions. | 523 // Do not notify debugger on stack overflow and out of memory exceptions. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
667 } | 698 } |
668 | 699 |
669 return DartLibraryCalls::InstanceCreate(library, | 700 return DartLibraryCalls::InstanceCreate(library, |
670 *class_name, | 701 *class_name, |
671 *constructor_name, | 702 *constructor_name, |
672 arguments); | 703 arguments); |
673 } | 704 } |
674 | 705 |
675 | 706 |
676 } // namespace dart | 707 } // namespace dart |
OLD | NEW |