| 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/code_patcher.h" | 7 #include "vm/code_patcher.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 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" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 const Function& function = Function::CheckedHandle(arguments.At(0)); | 107 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 108 const String& function_name = String::Handle(function.name()); | 108 const String& function_name = String::Handle(function.name()); |
| 109 const String& class_name = | 109 const String& class_name = |
| 110 String::Handle(Class::Handle(function.owner()).Name()); | 110 String::Handle(Class::Handle(function.owner()).Name()); |
| 111 OS::Print("< Exiting '%s.%s'\n", | 111 OS::Print("< Exiting '%s.%s'\n", |
| 112 class_name.ToCString(), function_name.ToCString()); | 112 class_name.ToCString(), function_name.ToCString()); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 // Allocation of a fixed length array of given element type. | 116 // Allocation of a fixed length array of given element type. |
| 117 // TODO(regis): This runtime entry is never called for allocating a List of a | 117 // This runtime entry is never called for allocating a List of a generic type, |
| 118 // generic type, which does not seem correct. Verify that generic user Lists are | 118 // because a prior run time call instantiates the element type if necessary. |
| 119 // properly supported. | |
| 120 // Arg0: array length. | 119 // Arg0: array length. |
| 121 // Arg1: array element type. | 120 // Arg1: array element type. |
| 122 // Return value: newly allocated array of length arg0. | 121 // Return value: newly allocated array of length arg0. |
| 123 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { | 122 DEFINE_RUNTIME_ENTRY(AllocateArray, 2) { |
| 124 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); | 123 ASSERT(arguments.Count() == kAllocateArrayRuntimeEntry.argument_count()); |
| 125 const Smi& length = Smi::CheckedHandle(arguments.At(0)); | 124 const Smi& length = Smi::CheckedHandle(arguments.At(0)); |
| 126 const Array& array = Array::Handle(Array::New(length.Value())); | 125 const Array& array = Array::Handle(Array::New(length.Value())); |
| 127 arguments.SetReturn(array); | 126 arguments.SetReturn(array); |
| 128 AbstractTypeArguments& element_type = | 127 AbstractTypeArguments& element_type = |
| 129 AbstractTypeArguments::CheckedHandle(arguments.At(1)); | 128 AbstractTypeArguments::CheckedHandle(arguments.At(1)); |
| 130 // An Array is raw or takes only one type argument. | 129 // An Array is raw or takes only one type argument. |
| 131 ASSERT(element_type.IsNull() || (element_type.Length() == 1)); | 130 ASSERT(element_type.IsNull() || |
| 131 ((element_type.Length() == 1) && element_type.IsInstantiated())); |
| 132 array.SetTypeArguments(element_type); // May be null. | 132 array.SetTypeArguments(element_type); // May be null. |
| 133 } | 133 } |
| 134 | 134 |
| 135 | 135 |
| 136 // Allocate a new object. | 136 // Allocate a new object. |
| 137 // Arg0: class of the object that needs to be allocated. | 137 // Arg0: class of the object that needs to be allocated. |
| 138 // Arg1: type arguments of the object that needs to be allocated. | 138 // Arg1: type arguments of the object that needs to be allocated. |
| 139 // Arg2: type arguments of the instantiator or kNoInstantiator. | 139 // Arg2: type arguments of the instantiator or kNoInstantiator. |
| 140 // Return value: newly allocated object. | 140 // Return value: newly allocated object. |
| 141 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { | 141 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 const String& dst_name = String::CheckedHandle(arguments.At(2)); | 670 const String& dst_name = String::CheckedHandle(arguments.At(2)); |
| 671 const String& malformed_error = String::CheckedHandle(arguments.At(3)); | 671 const String& malformed_error = String::CheckedHandle(arguments.At(3)); |
| 672 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); | 672 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); |
| 673 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); | 673 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); |
| 674 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 674 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 675 dst_type_name, dst_name, malformed_error); | 675 dst_type_name, dst_name, malformed_error); |
| 676 UNREACHABLE(); | 676 UNREACHABLE(); |
| 677 } | 677 } |
| 678 | 678 |
| 679 | 679 |
| 680 // TODO(regis): Function rest arguments are not supported anymore, but they may | |
| 681 // come back. | |
| 682 // Check that the type of each element of the given array is assignable to the | |
| 683 // given type. | |
| 684 // Arg0: index of the token of the rest argument declaration (source location). | |
| 685 // Arg1: rest argument array. | |
| 686 // Arg2: element declaration type. | |
| 687 // Arg3: type arguments of the instantiator of the element declaration type. | |
| 688 // Arg4: name of object being assigned to, i.e. name of rest argument. | |
| 689 // Return value: null if assignable, otherwise allocate and throw a TypeError. | |
| 690 DEFINE_RUNTIME_ENTRY(RestArgumentTypeCheck, 5) { | |
| 691 ASSERT(arguments.Count() == | |
| 692 kRestArgumentTypeCheckRuntimeEntry.argument_count()); | |
| 693 // TODO(regis): Get the token index from the PcDesc (via DartFrame). | |
| 694 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); | |
| 695 const Array& rest_array = Array::CheckedHandle(arguments.At(1)); | |
| 696 const AbstractType& element_type = | |
| 697 AbstractType::CheckedHandle(arguments.At(2)); | |
| 698 const AbstractTypeArguments& element_type_instantiator = | |
| 699 AbstractTypeArguments::CheckedHandle(arguments.At(3)); | |
| 700 const String& rest_name = String::CheckedHandle(arguments.At(4)); | |
| 701 ASSERT(!element_type.IsDynamicType()); // No need to check assignment. | |
| 702 ASSERT(!element_type.IsMalformed()); // Already checked in code generator. | |
| 703 ASSERT(!rest_array.IsNull()); | |
| 704 | |
| 705 Instance& elem = Instance::Handle(); | |
| 706 Error& malformed_error = Error::Handle(); | |
| 707 for (intptr_t i = 0; i < rest_array.Length(); i++) { | |
| 708 elem ^= rest_array.At(i); | |
| 709 // The previous successful type check may have set malformed_error. | |
| 710 // Note that a returned malformed_error is ignored if a type check succeeds. | |
| 711 malformed_error = Error::null(); | |
| 712 if (!elem.IsNull() && !elem.IsInstanceOf(element_type, | |
| 713 element_type_instantiator, | |
| 714 &malformed_error)) { | |
| 715 // Allocate and throw a new instance of TypeError. | |
| 716 char buf[256]; | |
| 717 OS::SNPrint(buf, sizeof(buf), "%s[%d]", | |
| 718 rest_name.ToCString(), static_cast<int>(i)); | |
| 719 const String& src_type_name = String::Handle(GetSimpleTypeName(elem)); | |
| 720 String& dst_type_name = String::Handle(); | |
| 721 if (!element_type.IsInstantiated()) { | |
| 722 // Instantiate element_type before reporting the error. | |
| 723 const AbstractType& instantiated_element_type = AbstractType::Handle( | |
| 724 element_type.InstantiateFrom(element_type_instantiator)); | |
| 725 dst_type_name = instantiated_element_type.Name(); | |
| 726 } else { | |
| 727 dst_type_name = element_type.Name(); | |
| 728 } | |
| 729 const String& dst_name = String::Handle(String::New(buf)); | |
| 730 String& malformed_error_message = String::Handle(); | |
| 731 if (!malformed_error.IsNull()) { | |
| 732 ASSERT(FLAG_enable_type_checks); | |
| 733 malformed_error_message = String::New(malformed_error.ToErrorCString()); | |
| 734 } | |
| 735 Exceptions::CreateAndThrowTypeError(location, src_type_name, | |
| 736 dst_type_name, dst_name, | |
| 737 malformed_error_message); | |
| 738 UNREACHABLE(); | |
| 739 } | |
| 740 } | |
| 741 } | |
| 742 | |
| 743 | |
| 744 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 680 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 745 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 681 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); |
| 746 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 682 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); |
| 747 Exceptions::Throw(exception); | 683 Exceptions::Throw(exception); |
| 748 } | 684 } |
| 749 | 685 |
| 750 | 686 |
| 751 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 687 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 752 ASSERT(arguments.Count() == kReThrowRuntimeEntry.argument_count()); | 688 ASSERT(arguments.Count() == kReThrowRuntimeEntry.argument_count()); |
| 753 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 689 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 } | 1480 } |
| 1545 } | 1481 } |
| 1546 } | 1482 } |
| 1547 // The cache is null terminated, therefore the loop above should never | 1483 // The cache is null terminated, therefore the loop above should never |
| 1548 // terminate by itself. | 1484 // terminate by itself. |
| 1549 UNREACHABLE(); | 1485 UNREACHABLE(); |
| 1550 return Code::null(); | 1486 return Code::null(); |
| 1551 } | 1487 } |
| 1552 | 1488 |
| 1553 } // namespace dart | 1489 } // namespace dart |
| OLD | NEW |