Chromium Code Reviews| 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 |