OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.h" | 7 #include "vm/assembler.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 DartFrameIterator iterator; | 107 DartFrameIterator iterator; |
108 StackFrame* caller_frame = iterator.NextFrame(); | 108 StackFrame* caller_frame = iterator.NextFrame(); |
109 ASSERT(caller_frame != NULL); | 109 ASSERT(caller_frame != NULL); |
110 return caller_frame->GetTokenPos(); | 110 return caller_frame->GetTokenPos(); |
111 } | 111 } |
112 | 112 |
113 | 113 |
114 // Allocate a new object. | 114 // Allocate a new object. |
115 // Arg0: class of the object that needs to be allocated. | 115 // Arg0: class of the object that needs to be allocated. |
116 // Arg1: type arguments of the object that needs to be allocated. | 116 // Arg1: type arguments of the object that needs to be allocated. |
117 // Arg2: type arguments of the instantiator or kNoInstantiator. | |
118 // Return value: newly allocated object. | 117 // Return value: newly allocated object. |
119 DEFINE_RUNTIME_ENTRY(AllocateObject, 3) { | 118 DEFINE_RUNTIME_ENTRY(AllocateObject, 2) { |
120 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); | 119 const Class& cls = Class::CheckedHandle(arguments.ArgAt(0)); |
121 const Instance& instance = Instance::Handle(Instance::New(cls)); | 120 const Instance& instance = Instance::Handle(Instance::New(cls)); |
122 arguments.SetReturn(instance); | 121 arguments.SetReturn(instance); |
123 if (cls.NumTypeArguments() == 0) { | 122 if (cls.NumTypeArguments() == 0) { |
124 // No type arguments required for a non-parameterized type. | 123 // No type arguments required for a non-parameterized type. |
125 ASSERT(Instance::CheckedHandle(arguments.ArgAt(1)).IsNull()); | 124 ASSERT(Instance::CheckedHandle(arguments.ArgAt(1)).IsNull()); |
126 return; | 125 return; |
127 } | 126 } |
128 TypeArguments& type_arguments = | 127 TypeArguments& type_arguments = |
129 TypeArguments::CheckedHandle(arguments.ArgAt(1)); | 128 TypeArguments::CheckedHandle(arguments.ArgAt(1)); |
130 // If no instantiator is provided, set the type arguments and return. | 129 // Unless null (for a raw type), the type argument vector may be longer than |
131 if (Object::Handle(arguments.ArgAt(2)).IsSmi()) { | 130 // necessary due to a type optimization reusing the type argument vector of |
132 ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() == | 131 // the instantiator. |
133 StubCode::kNoInstantiator); | 132 ASSERT(type_arguments.IsNull() || |
134 // Unless null (for a raw type), the type argument vector may be longer than | 133 (type_arguments.IsInstantiated() && |
135 // necessary due to a type optimization reusing the type argument vector of | 134 (type_arguments.Length() >= cls.NumTypeArguments()))); |
136 // the instantiator. | |
137 ASSERT(type_arguments.IsNull() || | |
138 (type_arguments.IsInstantiated() && | |
139 (type_arguments.Length() >= cls.NumTypeArguments()))); | |
140 instance.SetTypeArguments(type_arguments); // May be null. | |
141 return; | |
142 } | |
143 // A still uninstantiated type argument vector must have the correct length. | |
144 ASSERT(!type_arguments.IsInstantiated() && | |
145 (type_arguments.Length() == cls.NumTypeArguments())); | |
146 const TypeArguments& instantiator = | |
147 TypeArguments::CheckedHandle(arguments.ArgAt(2)); | |
148 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | |
149 // Code inlined in the caller should have optimized the case where the | |
150 // instantiator can be reused as type argument vector. | |
151 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); | |
152 if (FLAG_enable_type_checks) { | |
153 Error& bound_error = Error::Handle(); | |
154 type_arguments = | |
155 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, | |
156 &bound_error); | |
157 if (!bound_error.IsNull()) { | |
158 // Throw a dynamic type error. | |
159 const intptr_t location = GetCallerLocation(); | |
160 String& bound_error_message = String::Handle( | |
161 String::New(bound_error.ToErrorCString())); | |
162 Exceptions::CreateAndThrowTypeError( | |
163 location, Symbols::Empty(), Symbols::Empty(), | |
164 Symbols::Empty(), bound_error_message); | |
165 UNREACHABLE(); | |
166 } | |
167 } else { | |
168 type_arguments = | |
169 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); | |
170 } | |
171 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); | |
172 instance.SetTypeArguments(type_arguments); | 135 instance.SetTypeArguments(type_arguments); |
173 } | 136 } |
174 | 137 |
175 | 138 |
176 // Instantiate type. | 139 // Instantiate type. |
177 // Arg0: uninstantiated type. | 140 // Arg0: uninstantiated type. |
178 // Arg1: instantiator type arguments. | 141 // Arg1: instantiator type arguments. |
179 // Return value: instantiated type. | 142 // Return value: instantiated type. |
180 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { | 143 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { |
181 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); | 144 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); |
(...skipping 30 matching lines...) Expand all Loading... |
212 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { | 175 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { |
213 TypeArguments& type_arguments = | 176 TypeArguments& type_arguments = |
214 TypeArguments::CheckedHandle(arguments.ArgAt(0)); | 177 TypeArguments::CheckedHandle(arguments.ArgAt(0)); |
215 const TypeArguments& instantiator = | 178 const TypeArguments& instantiator = |
216 TypeArguments::CheckedHandle(arguments.ArgAt(1)); | 179 TypeArguments::CheckedHandle(arguments.ArgAt(1)); |
217 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); | 180 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); |
218 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 181 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
219 // Code inlined in the caller should have optimized the case where the | 182 // Code inlined in the caller should have optimized the case where the |
220 // instantiator can be reused as type argument vector. | 183 // instantiator can be reused as type argument vector. |
221 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); | 184 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); |
222 type_arguments = | 185 if (FLAG_enable_type_checks) { |
223 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); | 186 Error& bound_error = Error::Handle(); |
| 187 type_arguments = |
| 188 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, |
| 189 &bound_error); |
| 190 if (!bound_error.IsNull()) { |
| 191 // Throw a dynamic type error. |
| 192 const intptr_t location = GetCallerLocation(); |
| 193 String& bound_error_message = String::Handle( |
| 194 String::New(bound_error.ToErrorCString())); |
| 195 Exceptions::CreateAndThrowTypeError( |
| 196 location, Symbols::Empty(), Symbols::Empty(), |
| 197 Symbols::Empty(), bound_error_message); |
| 198 UNREACHABLE(); |
| 199 } |
| 200 } else { |
| 201 type_arguments = |
| 202 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); |
| 203 } |
224 ASSERT(type_arguments.IsInstantiated()); | 204 ASSERT(type_arguments.IsInstantiated()); |
225 arguments.SetReturn(type_arguments); | 205 arguments.SetReturn(type_arguments); |
226 } | 206 } |
227 | 207 |
228 | 208 |
229 // Allocate a new closure. | 209 // Allocate a new closure. |
230 // The type argument vector of a closure is always the vector of type parameters | 210 // The type argument vector of a closure is always the vector of type parameters |
231 // of its signature class, i.e. an uninstantiated identity vector. Therefore, | 211 // of its signature class, i.e. an uninstantiated identity vector. Therefore, |
232 // the instantiator type arguments can be used as the instantiated closure type | 212 // the instantiator type arguments can be used as the instantiated closure type |
233 // arguments and is passed here as the type arguments. | 213 // arguments and is passed here as the type arguments. |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 // of the given value. | 1593 // of the given value. |
1614 // Arg0: Field object; | 1594 // Arg0: Field object; |
1615 // Arg1: Value that is being stored. | 1595 // Arg1: Value that is being stored. |
1616 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1596 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
1617 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1597 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
1618 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1598 const Object& value = Object::Handle(arguments.ArgAt(1)); |
1619 field.UpdateGuardedCidAndLength(value); | 1599 field.UpdateGuardedCidAndLength(value); |
1620 } | 1600 } |
1621 | 1601 |
1622 } // namespace dart | 1602 } // namespace dart |
OLD | NEW |