| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 Exceptions::CreateAndThrowTypeError( | 581 Exceptions::CreateAndThrowTypeError( |
| 582 location, no_name, no_name, no_name, malformed_error_message); | 582 location, no_name, no_name, no_name, malformed_error_message); |
| 583 UNREACHABLE(); | 583 UNREACHABLE(); |
| 584 } | 584 } |
| 585 UpdateTypeTestCache(node_id, instance, type, instantiator, | 585 UpdateTypeTestCache(node_id, instance, type, instantiator, |
| 586 instantiator_type_arguments, result, cache); | 586 instantiator_type_arguments, result, cache); |
| 587 arguments.SetReturn(result); | 587 arguments.SetReturn(result); |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 // For error reporting, simplify type name, e.g, all integer types (Smi, Mint, | |
| 592 // Bigint) are reported as 'int' and all String types are mapped to 'String'. | |
| 593 static RawString* GetSimpleTypeName(const Instance& value) { | |
| 594 if (value.IsInteger()) { | |
| 595 return String::NewSymbol("int"); | |
| 596 } else if (value.IsString()) { | |
| 597 return String::NewSymbol("String"); | |
| 598 } else { | |
| 599 return Type::Handle(value.GetType()).Name(); | |
| 600 } | |
| 601 } | |
| 602 | |
| 603 | |
| 604 // Check that the type of the given instance is a subtype of the given type and | 591 // Check that the type of the given instance is a subtype of the given type and |
| 605 // can therefore be assigned. | 592 // can therefore be assigned. |
| 606 // Arg0: node-id of the assignment. | 593 // Arg0: node-id of the assignment. |
| 607 // Arg1: instance being assigned. | 594 // Arg1: instance being assigned. |
| 608 // Arg2: type being assigned to. | 595 // Arg2: type being assigned to. |
| 609 // Arg3: instantiator (or null). | 596 // Arg3: instantiator (or null). |
| 610 // Arg4: type arguments of the instantiator of the type being assigned to. | 597 // Arg4: type arguments of the instantiator of the type being assigned to. |
| 611 // Arg5: name of variable being assigned to. | 598 // Arg5: name of variable being assigned to. |
| 612 // Arg6: SubtypeTestCache. | 599 // Arg6: SubtypeTestCache. |
| 613 // Return value: instance if a subtype, otherwise throw a TypeError. | 600 // Return value: instance if a subtype, otherwise throw a TypeError. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 631 dst_type, instantiator_type_arguments, &malformed_error); | 618 dst_type, instantiator_type_arguments, &malformed_error); |
| 632 | 619 |
| 633 if (FLAG_trace_type_checks) { | 620 if (FLAG_trace_type_checks) { |
| 634 PrintTypeCheck("TypeCheck", | 621 PrintTypeCheck("TypeCheck", |
| 635 src_instance, dst_type, instantiator_type_arguments, | 622 src_instance, dst_type, instantiator_type_arguments, |
| 636 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); | 623 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); |
| 637 } | 624 } |
| 638 if (!is_instance_of) { | 625 if (!is_instance_of) { |
| 639 // Throw a dynamic type error. | 626 // Throw a dynamic type error. |
| 640 const intptr_t location = GetCallerLocation(); | 627 const intptr_t location = GetCallerLocation(); |
| 641 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); | 628 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 629 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 642 String& dst_type_name = String::Handle(); | 630 String& dst_type_name = String::Handle(); |
| 643 if (!dst_type.IsInstantiated()) { | 631 if (!dst_type.IsInstantiated()) { |
| 644 // Instantiate dst_type before reporting the error. | 632 // Instantiate dst_type before reporting the error. |
| 645 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 633 const AbstractType& instantiated_dst_type = AbstractType::Handle( |
| 646 dst_type.InstantiateFrom(instantiator_type_arguments)); | 634 dst_type.InstantiateFrom(instantiator_type_arguments)); |
| 647 dst_type_name = instantiated_dst_type.Name(); | 635 dst_type_name = instantiated_dst_type.UserVisibleName(); |
| 648 } else { | 636 } else { |
| 649 dst_type_name = dst_type.Name(); | 637 dst_type_name = dst_type.UserVisibleName(); |
| 650 } | 638 } |
| 651 String& malformed_error_message = String::Handle(); | 639 String& malformed_error_message = String::Handle(); |
| 652 if (!malformed_error.IsNull()) { | 640 if (!malformed_error.IsNull()) { |
| 653 ASSERT(FLAG_enable_type_checks); | 641 ASSERT(FLAG_enable_type_checks); |
| 654 malformed_error_message = String::New(malformed_error.ToErrorCString()); | 642 malformed_error_message = String::New(malformed_error.ToErrorCString()); |
| 655 } | 643 } |
| 656 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, | 644 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, |
| 657 dst_name, malformed_error_message); | 645 dst_name, malformed_error_message); |
| 658 UNREACHABLE(); | 646 UNREACHABLE(); |
| 659 } | 647 } |
| 660 UpdateTypeTestCache(node_id, src_instance, dst_type, | 648 UpdateTypeTestCache(node_id, src_instance, dst_type, |
| 661 dst_instantiator, instantiator_type_arguments, | 649 dst_instantiator, instantiator_type_arguments, |
| 662 Bool::ZoneHandle(Bool::True()), cache); | 650 Bool::ZoneHandle(Bool::True()), cache); |
| 663 arguments.SetReturn(src_instance); | 651 arguments.SetReturn(src_instance); |
| 664 } | 652 } |
| 665 | 653 |
| 666 | 654 |
| 667 // Report that the type of the given object is not bool in conditional context. | 655 // Report that the type of the given object is not bool in conditional context. |
| 668 // Arg0: bad object. | 656 // Arg0: bad object. |
| 669 // Return value: none, throws a TypeError. | 657 // Return value: none, throws a TypeError. |
| 670 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { | 658 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { |
| 671 ASSERT(arguments.Count() == | 659 ASSERT(arguments.Count() == |
| 672 kConditionTypeErrorRuntimeEntry.argument_count()); | 660 kConditionTypeErrorRuntimeEntry.argument_count()); |
| 673 const intptr_t location = GetCallerLocation(); | 661 const intptr_t location = GetCallerLocation(); |
| 674 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); | 662 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); |
| 675 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 663 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 676 const Type& bool_interface = Type::Handle(Type::BoolInterface()); | 664 const Type& bool_interface = Type::Handle(Type::BoolInterface()); |
| 677 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); | 665 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 678 const String& bool_type_name = String::Handle(bool_interface.Name()); | 666 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 667 const String& bool_type_name = |
| 668 String::Handle(bool_interface.UserVisibleName()); |
| 679 const String& expr = String::Handle(String::NewSymbol("boolean expression")); | 669 const String& expr = String::Handle(String::NewSymbol("boolean expression")); |
| 680 const String& no_malformed_type_error = String::Handle(); | 670 const String& no_malformed_type_error = String::Handle(); |
| 681 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 671 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
| 682 expr, no_malformed_type_error); | 672 expr, no_malformed_type_error); |
| 683 UNREACHABLE(); | 673 UNREACHABLE(); |
| 684 } | 674 } |
| 685 | 675 |
| 686 | 676 |
| 687 // Report that the type of the type check is malformed. | 677 // Report that the type of the type check is malformed. |
| 688 // Arg0: src value. | 678 // Arg0: src value. |
| 689 // Arg1: name of instance being assigned to. | 679 // Arg1: name of instance being assigned to. |
| 690 // Arg2: malformed type error message. | 680 // Arg2: malformed type error message. |
| 691 // Return value: none, throws an exception. | 681 // Return value: none, throws an exception. |
| 692 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { | 682 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 693 ASSERT(arguments.Count() == | 683 ASSERT(arguments.Count() == |
| 694 kMalformedTypeErrorRuntimeEntry.argument_count()); | 684 kMalformedTypeErrorRuntimeEntry.argument_count()); |
| 695 const intptr_t location = GetCallerLocation(); | 685 const intptr_t location = GetCallerLocation(); |
| 696 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); | 686 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); |
| 697 const String& dst_name = String::CheckedHandle(arguments.At(1)); | 687 const String& dst_name = String::CheckedHandle(arguments.At(1)); |
| 698 const String& malformed_error = String::CheckedHandle(arguments.At(2)); | 688 const String& malformed_error = String::CheckedHandle(arguments.At(2)); |
| 699 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); | 689 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); |
| 700 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); | 690 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); |
| 691 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 701 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 692 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 702 dst_type_name, dst_name, malformed_error); | 693 dst_type_name, dst_name, malformed_error); |
| 703 UNREACHABLE(); | 694 UNREACHABLE(); |
| 704 } | 695 } |
| 705 | 696 |
| 706 | 697 |
| 707 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 698 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 708 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 699 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); |
| 709 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 700 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); |
| 710 Exceptions::Throw(exception); | 701 Exceptions::Throw(exception); |
| (...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 } | 1562 } |
| 1572 } | 1563 } |
| 1573 } | 1564 } |
| 1574 // The cache is null terminated, therefore the loop above should never | 1565 // The cache is null terminated, therefore the loop above should never |
| 1575 // terminate by itself. | 1566 // terminate by itself. |
| 1576 UNREACHABLE(); | 1567 UNREACHABLE(); |
| 1577 return Code::null(); | 1568 return Code::null(); |
| 1578 } | 1569 } |
| 1579 | 1570 |
| 1580 } // namespace dart | 1571 } // namespace dart |
| OLD | NEW |