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/code_generator.cc

Issue 10368004: Properly set the element type of literal lists. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/code_generator_ia32.h » ('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) 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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/code_generator_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698