Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(720)

Side by Side Diff: runtime/vm/exceptions.cc

Issue 1778133002: Enumerate URIs of all types in type errors in order to help the user diagnose (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/exceptions.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/log.h"
13 #include "vm/object.h" 14 #include "vm/object.h"
14 #include "vm/object_store.h" 15 #include "vm/object_store.h"
15 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
16 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
17 #include "vm/symbols.h" 18 #include "vm/symbols.h"
18 #include "vm/tags.h" 19 #include "vm/tags.h"
19 20
20 namespace dart { 21 namespace dart {
21 22
22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, 23 DEFINE_FLAG(bool, print_stacktrace_at_throw, false,
23 "Prints a stack trace everytime a throw occurs."); 24 "Prints a stack trace everytime a throw occurs.");
24 25
25 26
26 const char* Exceptions::kCastErrorDstName = "type cast";
27
28
29 class StacktraceBuilder : public ValueObject { 27 class StacktraceBuilder : public ValueObject {
30 public: 28 public:
31 StacktraceBuilder() { } 29 StacktraceBuilder() { }
32 virtual ~StacktraceBuilder() { } 30 virtual ~StacktraceBuilder() { }
33 31
34 virtual void AddFrame(const Code& code, const Smi& offset) = 0; 32 virtual void AddFrame(const Code& code, const Smi& offset) = 0;
35 }; 33 };
36 34
37 35
38 class RegularStacktraceBuilder : public StacktraceBuilder { 36 class RegularStacktraceBuilder : public StacktraceBuilder {
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 362 }
365 } 363 }
366 } 364 }
367 // We expect to find a handler_pc, if the exception is unhandled 365 // We expect to find a handler_pc, if the exception is unhandled
368 // then we expect to at least have the dart entry frame on the 366 // then we expect to at least have the dart entry frame on the
369 // stack as Exceptions::Throw should happen only after a dart 367 // stack as Exceptions::Throw should happen only after a dart
370 // invocation has been done. 368 // invocation has been done.
371 ASSERT(handler_pc != 0); 369 ASSERT(handler_pc != 0);
372 370
373 if (FLAG_print_stacktrace_at_throw) { 371 if (FLAG_print_stacktrace_at_throw) {
374 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); 372 THR_Print("Exception '%s' thrown:\n", exception.ToCString());
375 OS::Print("%s\n", stacktrace.ToCString()); 373 THR_Print("%s\n", stacktrace.ToCString());
376 } 374 }
377 if (handler_exists) { 375 if (handler_exists) {
378 // Found a dart handler for the exception, jump to it. 376 // Found a dart handler for the exception, jump to it.
379 JumpToExceptionHandler(thread, 377 JumpToExceptionHandler(thread,
380 handler_pc, 378 handler_pc,
381 handler_sp, 379 handler_sp,
382 handler_fp, 380 handler_fp,
383 exception, 381 exception,
384 stacktrace); 382 stacktrace);
385 } else { 383 } else {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); 425 Class& cls = Class::Handle(core_lib.LookupClass(cls_name));
428 ASSERT(!cls.IsNull()); 426 ASSERT(!cls.IsNull());
429 // There are no parameterized error types, so no need to set type arguments. 427 // There are no parameterized error types, so no need to set type arguments.
430 return Instance::New(cls); 428 return Instance::New(cls);
431 } 429 }
432 430
433 431
434 // Allocate, initialize, and throw a TypeError or CastError. 432 // Allocate, initialize, and throw a TypeError or CastError.
435 // If error_msg is not null, throw a TypeError, even for a type cast. 433 // If error_msg is not null, throw a TypeError, even for a type cast.
436 void Exceptions::CreateAndThrowTypeError(TokenPosition location, 434 void Exceptions::CreateAndThrowTypeError(TokenPosition location,
437 const String& src_type_name, 435 const AbstractType& src_type,
438 const String& dst_type_name, 436 const AbstractType& dst_type,
439 const String& dst_name, 437 const String& dst_name,
440 const String& error_msg) { 438 const String& bound_error_msg) {
441 const Array& args = Array::Handle(Array::New(7)); 439 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead.
440 Zone* zone = Thread::Current()->zone();
441 const Array& args = Array::Handle(zone, Array::New(4));
442 442
443 ExceptionType exception_type = 443 ExceptionType exception_type =
444 (error_msg.IsNull() && dst_name.Equals(kCastErrorDstName)) ? 444 (bound_error_msg.IsNull() &&
445 kCast : kType; 445 (dst_name.raw() == Symbols::InTypeCast().raw())) ? kCast : kType;
446 446
447 DartFrameIterator iterator; 447 DartFrameIterator iterator;
448 const Script& script = Script::Handle(GetCallerScript(&iterator)); 448 const Script& script = Script::Handle(zone, GetCallerScript(&iterator));
449 intptr_t line; 449 intptr_t line;
450 intptr_t column = -1; 450 intptr_t column = -1;
451 if (script.HasSource()) { 451 if (script.HasSource()) {
452 script.GetTokenLocation(location, &line, &column); 452 script.GetTokenLocation(location, &line, &column);
453 } else { 453 } else {
454 script.GetTokenLocation(location, &line, NULL); 454 script.GetTokenLocation(location, &line, NULL);
455 } 455 }
456 // Initialize '_url', '_line', and '_column' arguments. 456 // Initialize '_url', '_line', and '_column' arguments.
457 args.SetAt(0, String::Handle(script.url())); 457 args.SetAt(0, String::Handle(zone, script.url()));
458 args.SetAt(1, Smi::Handle(Smi::New(line))); 458 args.SetAt(1, Smi::Handle(zone, Smi::New(line)));
459 args.SetAt(2, Smi::Handle(Smi::New(column))); 459 args.SetAt(2, Smi::Handle(zone, Smi::New(column)));
460 460
461 // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. 461 // Construct '_errorMsg'.
462 args.SetAt(3, src_type_name); 462 GrowableHandlePtrArray<const String> pieces(zone, 20);
463 args.SetAt(4, dst_type_name); 463
464 args.SetAt(5, dst_name); 464 // Print bound error first, if any.
465 args.SetAt(6, error_msg); 465 if (!bound_error_msg.IsNull() && (bound_error_msg.Length() > 0)) {
466 pieces.Add(bound_error_msg);
467 pieces.Add(Symbols::NewLine());
468 }
469
470 // If dst_type is malformed or malbounded, only print the embedded error.
471 if (!dst_type.IsNull()) {
472 const LanguageError& error = LanguageError::Handle(zone, dst_type.error());
473 if (!error.IsNull()) {
474 // Print the embedded error only.
475 pieces.Add(String::Handle(zone, Symbols::New(error.ToErrorCString())));
476 pieces.Add(Symbols::NewLine());
477 } else {
478 // Describe the type error.
479 if (!src_type.IsNull()) {
480 pieces.Add(Symbols::TypeQuote());
481 pieces.Add(String::Handle(zone, src_type.UserVisibleName()));
482 pieces.Add(Symbols::QuoteIsNotASubtypeOf());
483 }
484 pieces.Add(Symbols::TypeQuote());
485 pieces.Add(String::Handle(zone, dst_type.UserVisibleName()));
486 pieces.Add(Symbols::SingleQuote());
487 if (exception_type == kCast) {
488 pieces.Add(dst_name);
489 } else if (dst_name.Length() > 0) {
490 pieces.Add(Symbols::SpaceOfSpace());
491 pieces.Add(Symbols::SingleQuote());
492 pieces.Add(dst_name);
493 pieces.Add(Symbols::SingleQuote());
494 }
495 // Print URIs of src and dst types.
496 pieces.Add(Symbols::SpaceWhereNewLine());
497 if (!src_type.IsNull()) {
498 pieces.Add(String::Handle(zone, src_type.EnumerateURIs()));
499 }
500 if (!dst_type.IsDynamicType() && !dst_type.IsVoidType()) {
501 pieces.Add(String::Handle(zone, dst_type.EnumerateURIs()));
502 }
503 }
504 }
505 const String& error_msg =
506 String::Handle(zone, Symbols::FromConcatAll(pieces));
507 args.SetAt(3, error_msg);
466 508
467 // Type errors in the core library may be difficult to diagnose. 509 // Type errors in the core library may be difficult to diagnose.
468 // Print type error information before throwing the error when debugging. 510 // Print type error information before throwing the error when debugging.
469 if (FLAG_print_stacktrace_at_throw) { 511 if (FLAG_print_stacktrace_at_throw) {
470 if (!error_msg.IsNull()) { 512 THR_Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
471 OS::Print("%s\n", error_msg.ToCString()); 513 String::Handle(zone, script.url()).ToCString(), line, column);
472 } 514 THR_Print("%s\n", error_msg.ToCString());
473 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
474 String::Handle(script.url()).ToCString(), line, column);
475 if (!dst_name.IsNull() && (dst_name.Length() > 0)) {
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 } 515 }
484 516
485 // Throw TypeError or CastError instance. 517 // Throw TypeError or CastError instance.
486 Exceptions::ThrowByType(exception_type, args); 518 Exceptions::ThrowByType(exception_type, args);
487 UNREACHABLE(); 519 UNREACHABLE();
488 } 520 }
489 521
490 522
491 void Exceptions::Throw(Thread* thread, const Instance& exception) { 523 void Exceptions::Throw(Thread* thread, const Instance& exception) {
492 // Do not notify debugger on stack overflow and out of memory exceptions. 524 // Do not notify debugger on stack overflow and out of memory exceptions.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 699 }
668 700
669 return DartLibraryCalls::InstanceCreate(library, 701 return DartLibraryCalls::InstanceCreate(library,
670 *class_name, 702 *class_name,
671 *constructor_name, 703 *constructor_name,
672 arguments); 704 arguments);
673 } 705 }
674 706
675 707
676 } // namespace dart 708 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/exceptions.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698